如果循环all()any(),卡在pandas中?

时间:2017-12-06 09:55:07

标签: python python-3.x pandas

我尝试编写一些基本函数,发现我完全陷入了一个关于在python pandas数据帧上使用if elif else的一个非常简单的问题。这是一个例子: 虚拟数据:

d = {'x': [1, 2, 0, -2, -2], 'y': [3, 4, 5, 4, -4]}
df = pd.DataFrame(data=d)

我的职能:

def cart2sph(data):  #ceval indicates using numerical expressions
    newDF = pd.DataFrame()
    x = data['x'].astype(float)
    y = data['y'].astype(float)
    if (x == 0).all():
      newDF['angle'] = sign(y)* pi / 2
    else:
      newDF['angle'] = arctan(y/x)
    if (x < 0 and y >= 0).all():
      newDF['angle'] += pi
    elif (x < 0 and y < 0).all():
      newDF['angle'] -= pi
    return newDF

我总是收到以下错误:

Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 11, in cart2sph File "C:\Users\tpotrusil\AppData\Local\Programs\Python\Python36\lib\site-packages\pandas\core\generic.py", line 955, 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().

......并且看不到问题!?!

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:2)

尝试更换 (x < 0 and y >= 0).all() 通过 (x < 0).all() and (y >= 0).all()

答案 1 :(得分:0)

看起来你误解了.all()的作用。如果if列中的所有值严格为负,则您的第二个elif语句(以及以下x)只能为真。鉴于您正在计算每个点的原点角度,您实际上想要分别考虑每一行。

我认为您正在寻找以下内容,它会将角度公式应用于每一行,而不是整个数据帧。

def cart2sph(row):
    ''' Called on each (x, y) row of the dataframe. '''
    x, y = row[['x', 'y']]
    if x == 0:
        angle = sign(y)* pi / 2
    else:
        angle = arctan(y/x)
    if (x < 0) & (y >= 0):
        angle += pi
    elif (x < 0) & (y < 0):
        angle -= pi
    return angle

angles = df.apply(cart2sph, axis=1)

通过矢量化还有一种更快的方法可以实现这一点,如果您的数据帧很大,这应该可以提供更好的性能:

# Split the x==0/x!=0 cases and recombine (vectorises the first if statement)
angles = pd.concat([
    arctan(df.y / df.x)[df.x != 0],
    (sign(df.y) * pi / 2)[df.x == 0]]).sort_index()

# Add/subtract for specific cases (vectorises the second if statement)
angles[(df.x < 0) & (df.y >= 0)] += pi
angles[(df.x < 0) & (df.y < 0)] -= pi