假设我有以下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)会选择整个列,因此所有它们都将从同一列中选择,这不是我想要的。使用矢量化熊猫方法有更好的方法吗?
答案 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))])