我尝试编写一些基本函数,发现我完全陷入了一个关于在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().
......并且看不到问题!?!
非常感谢任何帮助!
答案 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