为 pandas 数据帧的每一行随机采样非空列值

Randomly sample non-empty column values for each row of a pandas dataframe

对于每一行,我想随机抽取 k 个对应于非空值的列索引。

如果我从这个数据框开始,

A = pd.DataFrame([
    [1, np.nan, 3, 5],
    [np.nan, 2, np.nan, 7],
    [4, 8, 9]
])
>>> A
    0   1   2   3
0   1.0 NaN 3.0 5.0
1   NaN 2.0 NaN 7.0
2   4.0 8.0 9.0 NaN

如果我想为每一行随机抽取 2 个非空值并将它们更改为值 -1,可以这样做的一种方法如下:

B = A.copy()

for i in A.index:
    s = A.loc[i]
    s = s[s.notnull()]
    col_idx = random.sample(s.index.tolist(), 2)
    B.iloc[i, col_idx] = -1

>>> B
    0   1   2   3
0   -1.0    NaN -1.0    5.0
1   NaN -1.0    NaN -1.0
2   -1.0    -1.0    9.0 NaN

在 Pandas 中是否有更好的本地方式来避免使用 for 循环? pandas.DataFrame.sample 方法似乎使每行中采样的列数保持不变。但是如果数据框有空洞,每行的非空值的数量就不会是常量。

在你的情况下 stack groupbysample ,将值 update 改回

s = A.stack().groupby(level=0).sample(n=2)
s[:] = -1
A.update(s.unstack())
A
Out[122]: 
     0    1    2    3
0  1.0  NaN -1.0 -1.0
1  NaN -1.0  NaN -1.0
2 -1.0  8.0 -1.0  NaN