我有以下数据框:
S A
1 1
1 0
2 1
2 0
我想创建一个新的'Result'
列,该列是根据A列和S列的值计算的。
我编写了以下嵌套的np.where
代码
df['Result'] = np.where((df.S == 1 & df.A == 1), 1,
(df.S == 1 & df.A == 0), 0,
(df.S == 2 & df.A == 1), 0,
(df.S == 2 & df.A == 0), 1))))
但是当我执行它时,出现以下错误:
SyntaxError: invalid syntax
我的代码有什么问题?
答案 0 :(得分:1)
据我所知np.where
不支持多个return语句(至少不超过两个)。因此,要么重写np.where
来生成一个True和False语句,然后为True / False返回1/0,或者您需要使用掩码。
如果重写np.where
,则只能使用两个结果,并且当条件不为True时,将始终设置第二个结果。因此,还将为(S == 5) & (A = np.nan)
之类的值进行设置。
df['Result'] = np.where(((df.S == 1) & (df.A == 1)) | ((df.S == 2) & (df.A == 0)), 1, 0)
使用遮罩时,可以应用任意数量的条件和结果。对于您的示例,解决方案如下:
mask_0 = ((df.S == 1) & (df.A == 0)) | ((df.S == 2) & (df.A == 1))
mask_1 = ((df.S == 1) & (df.A == 1)) | ((df.S == 2) & (df.A == 0))
df.loc[mask_0, 'Result'] = 0
df.loc[mask_1, 'Result'] = 1
在不满足任何条件的情况下,结果将设置为np.nan
。这是不安全的,因此应使用。但是,如果您想在这些位置使用零,只需用零初始化Results
列即可。
当然,对于特殊情况(例如仅包含1和0的情况)可以简化此操作,而通过使用dict或其他容器将其扩展为任意数量的结果。
答案 1 :(得分:1)
您应该使用嵌套的np.where。就像sql case子句。但是,当数据中存在nan时要小心。
df=pd.DataFrame({'S':[1,1,2,2],'A':[1,0,1,0]})
df['Result'] = np.where((df.S == 1) & (df.A == 1), 1, #when... then
np.where((df.S == 1) & (df.A == 0), 0, #when... then
np.where((df.S == 2) & (df.A == 1), 0, #when... then
1))) #else
df
| | S | A | Result |
|---|---|---|--------|
| 0 | 1 | 1 | 1 |
| 1 | 1 | 0 | 0 |
| 2 | 2 | 1 | 0 |
| 3 | 2 | 0 | 1 |
答案 2 :(得分:0)
如果您有非常嵌套的操作,我建议您使用numpy.select。
df = pd.DataFrame({
"S": [1, 1, 2, 2],
"A": [1, 0, 1, 0]
})
# you could of course combine the clause (1, 4) and (2, 3) with the '|' or operator
df['RESULT'] = np.select([
(df.S == 1) & (df.A == 1),
(df.S == 1) & (df.A == 0),
(df.S == 2) & (df.A == 1),
(df.S == 2) & (df.A == 0)
], [1, 0, 0, 1])