我有一个 Pandas 数据框,df。假设它看起来像这样:
A B C
1 1 4 7
2 2 5 8
3 3 6 9
我想添加一个新列 D,它是 B 列和 C 列的函数。它是 B 列和 C 列的哪个函数应该取决于 A 列的值。(这与我的一个 previous question 有点相关,但阅读它不是回答这个问题所必需的。)
为了本练习的目的,假设我希望当 A 小于 1.5 时 D 为 B + C,当 A 大于 2.5 时为 B * C,当 A 介于 1.5 和 2.5 之间时为 0。新数据框应如下所示:
A B C D
1 1 4 7 11
2 2 5 8 0
3 3 6 9 54
我的解决方案如下:
df['D'] = 0.
df.loc[dtfr.A.lt(1.5), 'D'] = dtfr.B + dtfr.C
df.loc[dtfr.B.gt(2.5), 'D'] = dtfr.B * dtfr.C
问题来了。此函数需要在大约一千个数据帧上运行,每个数据帧都是从大型文件数据库中的单个文件编译而来的。有时 - 很少,但有时 - 数据框将不包含为其中一个 df.loc[] 中的第一个语句返回“True”的单个值。例如,一个数据框中的所有值可能都小于 2.5,如本示例数据框中所示。
A B C
1 0 4 7
2 1 5 8
3 2 6 9
当我尝试运行解决方案的第三行时...
df.loc[dtfr.B.gt(2.5), 'D'] = dtfr.B * dtfr.C
...df.loc[dtfr.B.gt(2.5), 'D'] 的形状是 (0,),这会导致赋值抛出 ValueError。
ValueError: array is not broadcastable to correct shape
有没有比 try/except for ValueError 更安全的方法来处理这个问题,这看起来风险很大?
最佳答案
这是使用 numpy select
的另一种方式 (documentation here)语法非常简洁:
df['D'] = np.select( [ df.A < 1.5, df.A > 2.5 ],
[ df.B + df.C, df.B * df.C ], default=0 )
A B C D
1 1 4 7 11
2 2 5 8 0
3 3 6 9 54
它默认为零,但为了完整性我添加了它。我想感谢 @DSM 或 @HappyLeapSecond(我想是其中之一?)几个月前在答案中使用了这个,但我现在找不到那个帖子了。
此外,这是@AmiTavory 的回答 FWIW 的替代语法。
df['D'] = 0
df.D = np.where( df.A < 1.5, df.B + df.C, df.D )
df.D = np.where( df.A > 2.5, df.B * df.C, df.D )
关于python - 处理从 pandas.df.loc 到空选择的分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31347952/