编辑:此笔记本中发布的解决方案。特别感谢Étienne Célèry和ifly6
我正试图找出如何战胜令人恐惧的错误:
ValueError:序列的真值不明确。使用a.empty、a.bool((、a.item((、.any((或.all((。
d = {
'nickname': ['bobg89', 'coolkid34','livelaughlove38'],
'state': ['NY', 'CA','TN'],
'score': [100, 200,300]
}
df = pd.DataFrame(data=d)
df_2 = df.copy() #for use in the second non-lambda part
print(df)
这个输出:
nickname state score
0 bobg89 NY 100
1 coolkid34 CA 200
2 livelaughlove38 TN 300
如果他们来自纽约,那么我们的目标是将比分加50。
def add_some_love(state_value,score_value,name):
if state_value == name:
return score_value + 50
else:
return score_value
然后我们可以将该函数与lambda
函数一起应用。
df['love_added'] = df.apply(lambda x: add_some_love(x.state, x.score, 'NY'), axis=1)
print(df)
这让我们:
nickname state score love_added
0 bobg89 NY 100 150
1 coolkid34 CA 200 200
2 livelaughlove38 TN 300 300
这是我尝试在没有lambda的情况下编写它的地方,这就是我得到错误的地方。
@MSeifert在这里的回答似乎解释了为什么会发生这种情况(函数查看的是整列,而不是列中的一行,但我也认为将axis = 1
传递到.apply()
方法中会按行应用函数,并解决问题(。
所以我这样做:
df2['love_added'] = df2.apply(add_some_love(df2.state, df2.score, 'NY'), axis=1)
print(df2)
然后你会得到错误:
ValueError:序列的真值不明确。使用a.empty、a.bool((、a.item((、.any((或.all((。
所以我尝试了这些解决方案,但我似乎不知道如何重写add_some_love()
函数,以便在没有lambda函数的情况下正常运行。
有人有什么建议吗?
非常感谢您的时间和考虑。
您可以使用np.where
:
df['score'] = np.where(df['state'] == 'NY', df['score'] + 50, df['score'])
这将产生与您应用的函数相同的结果,同时也更具性能。
不使用lambda函数的问题是,实际上并没有将行传递给函数。你实际传递的是整个列df['score']
,因为这就是你告诉计算机要做的
你的功能中发生了什么,计算机在问:
# if state_value == name ...
if df['score'] == 'NY':
...
这自然会引起错误,因为df['score'] == 'NY'
是一系列布尔变量,而不是if
语句所需的单个布尔变量。
add_some_love
函数需要一个字符串输入才能执行比较if state_value == name
。在DataFrame上应用lambda
函数时,可以将每个单元格传递给该函数,而不是整个Series。
如果没有lambda
函数,就无法使用精确的add_some_love
函数。
如果您仍然想使用apply()
,请尝试以下功能:
def add_some_love(row, name):
if row.state == name:
row.score = row.score + 50
return row
df_2 = df_2.apply(add_some_love, axis=1, args=('NY',))
然而,这应该是最快、最有效的:
FILTER = df_2['state'] == 'NY'
df_2.loc[FILTER, 'score'] = df_2.loc[FILTER, 'score'] + 50