错误:系列的真值是不明确的 - Python pandas

时间:2017-08-03 20:26:40

标签: python pandas logic

我知道之前已经问过这个问题,但是,当我尝试做if语句并且我收到错误时。我查看了这个link,但在我的案例中并没有多大帮助。我的dfs是一个DataFrame列表。

我正在尝试以下内容,

for i in dfs:
    if (i['var1'] < 3.000):
       print(i)

给出以下错误:

  

ValueError:系列的真值是不明确的。使用a.empty,a.bool(),a.item(),a.any()或a.all()。

AND 我尝试了以下操作并收到同样的错误。

for i,j in enumerate(dfs):
    if (j['var1'] < 3.000):
       print(i)

我的var1数据类型为float32。我没有使用任何其他logical运算符和&|。在上面的链接中,似乎是因为使用了逻辑运算符。为什么我会获得ValueError

3 个答案:

答案 0 :(得分:6)

这是一个小型演示,展示了为什么会发生这种情况:

In [131]: df = pd.DataFrame(np.random.randint(0,20,(5,2)), columns=list('AB'))

In [132]: df
Out[132]:
    A   B
0   3  11
1   0  16
2  16   1
3   2  11
4  18  15

In [133]: res = df['A'] > 10

In [134]: res
Out[134]:
0    False
1    False
2     True
3    False
4     True
Name: A, dtype: bool

当我们尝试检查此系列是否为True时 - 熊猫不知道该怎么做:

In [135]: if res:
     ...:     print(df)
     ...:
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
...
skipped
...
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

解决方法:

我们可以决定如何处理一系列布尔值 - 例如if如果所有值为True则应返回True

In [136]: res.all()
Out[136]: False

至少一个值为True:

In [137]: res.any()
Out[137]: True

In [138]: if res.any():
     ...:     print(df)
     ...:
    A   B
0   3  11
1   0  16
2  16   1
3   2  11
4  18  15

答案 1 :(得分:2)

目前,您正在选择整个系列进行比较。要从系列中获取单个值,您需要使用以下内容:

for i in dfs:
if (i['var1'].iloc[0] < 3.000):
   print(i)

要比较每个单独的元素,你可以使用series.iteritems(文档在这篇文章中是稀疏的),如下所示:

for i in dfs:
    for _, v in i['var1'].iteritems():
        if v < 3.000:
            print(v)

对于大多数情况,更好的解决方案是选择数据帧的子集以用于您需要的任何内容,例如:

for i in dfs:
    subset = i[i['var1'] < 3.000]
    # do something with the subset

使用系列操作而不是迭代单个值时,大型数据帧上的pandas性能要快得多。有关详细信息,请查看pandas documentation on selection.

答案 2 :(得分:0)

比较返回一个值范围,例如,您需要通过any()或all()限制它,

     if((df[col] == ' this is any string or list').any()):
       return(df.loc[df[col] == temp].index.values.astype(int)[0])