Skip to main content
 首页 » 编程设计

python之处理从 pandas.df.loc 到空选择的分配

2025年05月04日32mq0036

我有一个 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 )