在 DataFrame 的布尔切片上设置时进行广播会产生奇怪的结果

P.J*_*.Jo 5 python pandas array-broadcasting

考虑以下代码:

import numpy as np
import pandas as pd

df = pd.DataFrame(
    {"AAA": [4, 5, 6, 7], "BBB": [10, 20, 30, 40], "CCC": [100, 50, -30, -50]}
)

df[[True, False, False, True]] = np.array([2,5]).reshape(2,1) 
df
   AAA  BBB  CCC
0    2    2    2
1    5   20   50
2    6   30  -30
3    5    5    5
Run Code Online (Sandbox Code Playgroud)

这将广播应用于数据帧,并导致第一行仅包含值 2,第四行仅包含值 5。正如我所料。现在,我只需向 df 添加一列并应用类似的转换:

df["logic"] = 9

df[[True, False, False, True]] = np.array([3,7]).reshape(2,1)

Run Code Online (Sandbox Code Playgroud)

我现在得到的不是提供仅包含 3 的第一行和仅包含 7 的最后一行

ValueError:使用 ndarray 设置时必须具有相等的 len 键和值

有人可以解释一下,为什么会发生这种情况?

moz*_*way 1

我认为这是 pandas 如何检查右侧数组的有效性的一个缺点,并且按照这种检查的想法,甚至df[[True, False, False, True]] = np.array([2,5]).reshape(2,1) 应该失败。

解决方法是显式广播:

target = np.array([3, 7])

df[[True, False, False, True]] = np.repeat(target[:, None], df.shape[1], axis=1)
Run Code Online (Sandbox Code Playgroud)

或者:

df[[True, False, False, True]] = np.broadcast_to(target[:,None], (2, df.shape[1]))
Run Code Online (Sandbox Code Playgroud)