我正在尝试在数据帧上应用if条件,但我遗漏了一些东西(错误:系列的真值是不明确的。使用a.empty,a.bool(),a.item() ,a.any()或a.all()。)
raw_data = {'age1': [23,45,21],'age2': [10,20,50]}
df = pd.DataFrame(raw_data, columns = ['age1','age2'])
def my_fun (var1,var2,var3):
if (df[var1]-df[var2])>0 :
df[var3]=df[var1]-df[var2]
else:
df[var3]=0
print(df[var3])
my_fun('age1','age2','diff')
答案 0 :(得分:10)
您可以使用numpy.where
:
def my_fun (var1,var2,var3):
df[var3]= np.where((df[var1]-df[var2])>0, df[var1]-df[var2], 0)
return df
df1 = my_fun('age1','age2','diff')
print (df1)
age1 age2 diff
0 23 10 13
1 45 20 25
2 21 50 0
错误更好地解释here。
apply
更慢的解决方案,需要axis=1
按行进行数据处理:
def my_fun(x, var1, var2, var3):
print (x)
if (x[var1]-x[var2])>0 :
x[var3]=x[var1]-x[var2]
else:
x[var3]=0
return x
print (df.apply(lambda x: my_fun(x, 'age1', 'age2','diff'), axis=1))
age1 age2 diff
0 23 10 13
1 45 20 25
2 21 50 0
也可以使用loc
,但有时可以覆盖数据:
def my_fun(x, var1, var2, var3):
print (x)
mask = (x[var1]-x[var2])>0
x.loc[mask, var3] = x[var1]-x[var2]
x.loc[~mask, var3] = 0
return x
print (my_fun(df, 'age1', 'age2','diff'))
age1 age2 diff
0 23 10 13.0
1 45 20 25.0
2 21 50 0.0
答案 1 :(得分:5)
您可以使用pandas.Series.where
df.assign(age3=(df.age1 - df.age2).where(df.age1 > df.age2, 0))
age1 age2 age3
0 23 10 13
1 45 20 25
2 21 50 0
您可以将其包装在函数
中def my_fun(v1, v2):
return v1.sub(v2).where(v1 > v2, 0)
df.assign(age3=my_fun(df.age1, df.age2))
age1 age2 age3
0 23 10 13
1 45 20 25
2 21 50 0
答案 2 :(得分:1)
没有np.where
或pd.Series.where
还有另一种方式。我并不是说它更好,但是在尝试使这个解决方案适应今天的一个具有挑战性的问题后,发现where
的语法并不那么直观。最后,不确定它是否可以在哪里,但是发现下面的方法可以让你在修改它之前看一下这个子集,这对我来说更快地找到了解决方案。当然也适用于OP。
你故意在一个数据帧的片上设置一个值为Pandas,所以经常警告你不要这样做。
This回答显示了正确的方法。
以下为您提供切片:
df.loc[df['age1'] - df['age2'] > 0]
..看起来像:
age1 age2
0 23 10
1 45 20
在原始数据框中为要修改切片后要保留的值添加一个额外的列:
df['diff'] = 0
现在修改切片:
df.loc[df['age1'] - df['age2'] > 0, 'diff'] = df['age1'] - df['age2']
..结果:
age1 age2 diff
0 23 10 13
1 45 20 25
2 21 50 0