在比较数据框中的列时,我在理解pandas行为方面遇到了一些麻烦。我想要做的是将逻辑操作应用于不同的列,并根据逻辑结果生成一个结果列,其值为True或False。 (逻辑也可能适用于使用.shift()生成的滞后列值,但我不认为这个问题是必要的。)
问题是我理解比较df.A< df.B是矢量化的(因此它非常快)并且应该按元素结果生成元素。这在我分配给一个系列时有效,但是当我尝试将它分配给一个新列时,它会出错。这是一个例子:
df = pd.DataFrame(np.random.randn(10,2),index=(np.arange(10)),columns=['A','B'])
df['C'] = False # must add column with [] notation rather than .C
a = df.A < df.B
df.C = A
df
这会产生预期的输出:
A B C
0 1.222631 0.568988 False
1 -0.719666 0.733197 True
2 -2.434720 -0.131745 True
3 0.653228 0.428794 False
4 0.862103 0.402158 False
5 -0.256027 -0.819937 False
6 -1.728418 1.463709 True
7 -1.110928 -2.173016 False
8 0.656576 -1.218179 False
9 0.014519 -0.854039 False
所以,继续并尝试不经过分配系列的中间步骤:
df['C'] = False # not necessary but a reset
if df.A < df.B: df.C = True
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
所以这里的问题是为什么当我第一次浏览该系列时这是否有效,但不能直接分配给该列?我怀疑有更多关于这种行为,我不明白。
让我继续一个相关的例子。我知道np.where()可能比使用if语句更清晰地进行这样的操作,但我仍然遇到一个指向缺乏理解的问题。以下是我认为应该相同的三行:
df['C'] = np.where((df.A < 0 & df.B > df.A), True, False) #1 Errors
df['C'] = np.where((df.A < 0) and (df.B > df.A), True, False) #2 Errors
df['C'] = np.where((df.A < 0) & (df.B > df.A), True, False) #3 Works
#2和#3之间的差异是和vs&amp; ...我怀疑在幕后我有点不太明白。但为什么Ex 1出错?不需要额外的括号,对吗? 条件1&amp;条件2 (条件1)&amp; (条件2)
为什么会产生不同的结果?更重要的是,这在哪里记录?只是尝试扩展自己的学习和理解,并学习如何处理这样的问题。
谢谢!
答案 0 :(得分:2)
回答你的问题,
Ans:我认为这是由“if”引起的。 您可以将“if”视为一个函数,它只接受True / False或具有已知True / False评估的函数(即,如果为1,如果为-1,如果为0,如果为None)。你可以参考https://docs.python.org/2/library/stdtypes.html。基本上python中的所有东西都在扩展对象类。如果该类具有非零或 len 的实现,则“if”应该正常工作。您可以尝试以下方法:
>>> x = 1
>>> x.__nonzero__()
True
>>> x = df.C
>>> x.__nonzero__()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Python/2.7/site-packages/pandas/core/generic.py", line 731, in __nonzero__
.format(self.__class__.__name__))
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
如果您仍想了解更多详情,我会将您推荐给pandas源代码https://github.com/pydata/pandas/blob/master/pandas/core/generic.py
如果您检查错误消息,
>>> df.B>df.A & df.A <0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Python/2.7/site-packages/pandas/core/ops.py", line 786, in wrapper
return filler(self._constructor(na_op(self.values, other.values),
File "/Library/Python/2.7/site-packages/pandas/core/ops.py", line 758, in na_op
result = lib.vec_binop(x, y, op)
File "pandas/lib.pyx", line 914, in pandas.lib.vec_binop (pandas/lib.c:16248)
File "pandas/lib.pyx", line 907, in pandas.lib.vec_binop (pandas/lib.c:16122)
TypeError: unsupported operand type(s) for &: 'float' and 'bool'
实际上意味着&amp;运算符试图在float和bool之间使用。浮子在哪里,布尔在哪里? bool是df.B&gt; df.A,浮子是df.A.这意味着什么?这意味着&amp;没有运算符优先级(&lt;,&gt;),请检查此https://www.ibiblio.org/swaroopch/byteofpython/read/operator-precedence.html
另一方面,“和”的运算符优先于(&lt;,&gt;),因此有效。
为了进一步深入挖掘,我相信检查源代码将是一个好方法。 希望它能回答你的问题。