熊猫:从每一行的随机列中选择值

时间:2019-07-25 12:18:56

标签: python pandas dataframe random

假设我有以下Pandas DataFrame:

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

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

0    7
1    2
2    9
dtype: int64

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

我知道可以通过遍历行并使用random.choice选择每一行来做到这一点,但是可以这么说,遍历行不仅性能差,而且“泛函”。另外,df.sample(axis = 1)会选择整个列,因此所有它们都将从同一列中选择,这不是我想要的。使用矢量化熊猫方法有更好的方法吗?

5 个答案:

答案 0 :(得分:4)

可能类似于:

pd.Series([np.random.choice(i,1)[0] for i in df.values])

答案 1 :(得分:3)

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

import numpy as np

indices = np.random.choice(np.arange(len(df.columns)), len(df), replace=True)

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

然后使用它来切片numpy数组:

df['random'] = df.to_numpy()[np.arange(len(df)), indices]

结果:

   a  b  c  random
0  1  4  7       7
1  2  5  8       5
2  3  6  9       9

答案 2 :(得分:1)

这可以完成工作(使用内置模块random):

ddf = df.apply(lambda row : random.choice(row.tolist()), axis=1)

或使用pandas sample

ddf = df.apply(lambda row : row.sample(), axis=1)

两者的行为相同。 ddf是您的系列。

答案 3 :(得分:1)

pd.DataFrame(
    df.values[range(df.shape[0]), 
                   np.random.randint(
                       0, df.shape[1], size=df.shape[0])])

输出

    0
0   4
1   5
2   9

答案 4 :(得分:1)

在选择每一行中的随机值时,您可能仍然需要遍历每一行-无论是使用for循环显式执行还是使用您决定调用的任何函数隐式执行。

但是,如果适合您的样式,则可以使用列表理解将其简化为一行:

result = pd.Series([random.choice(pd.iloc[i]) for i in range(len(df))])