Pandas:从每行的随机列中选择值

Rod*_*dia 5 python random dataframe pandas

假设我有以下 Pandas DataFrame:

df = pd.DataFrame({
    'a': [1, 2, 3],
    'b': [4, 5, 6],
    'c': [7, 8, 9]
})
Run Code Online (Sandbox Code Playgroud)
    a   b   c
0   1   4   7
1   2   5   8
2   3   6   9

Run Code Online (Sandbox Code Playgroud)

我想生成一个新的值pandas.Series,以便从 DataFrame 中的随机列中逐行选择该系列的值。因此,可能的输出是该系列:

0    7
1    2
2    9
dtype: int64
Run Code Online (Sandbox Code Playgroud)

(其中,在第 0 行中,它随机选择了“c”,在第 1 行中,它随机选择了“a”,在第 2 行中,它再次随机选择了“c”)。

我知道这可以通过迭代行并使用random.choice选择每一行来完成,但是迭代行不仅性能不佳,而且可以说是“unpandonic”。另外, df.sample(axis=1) 会选择整个列,因此所有列都会从同一列中选择,这不是我想要的。有没有更好的方法来使用矢量化的 pandas 方法来做到这一点?

ank*_*_91 5

可能是这样的:

pd.Series([np.random.choice(i,1)[0] for i in df.values])
Run Code Online (Sandbox Code Playgroud)


the*_*orm 5

这是一个完全矢量化的解决方案。但请注意,它不使用 Pandas 方法,而是涉及对底层 numpy 数组的操作。

import numpy as np

indices = np.random.choice(np.arange(len(df.columns)), len(df), replace=True)
Run Code Online (Sandbox Code Playgroud)

示例输出[1, 2, 1]对应于['b', 'c', 'b'].

然后用它来切片 numpy 数组:

df['random'] = df.to_numpy()[np.arange(len(df)), indices]
Run Code Online (Sandbox Code Playgroud)

结果:

   a  b  c  random
0  1  4  7       7
1  2  5  8       5
2  3  6  9       9
Run Code Online (Sandbox Code Playgroud)