通过随机抽样其他列数据创建新列

共4个回答,已解决, 标签: python pandas

我想通过随机采样其余列中的数据来创建一个新列。

请考虑具有 "N" 列的数据框, 如下所示:

|---------------------|------------------|---------------------|
|      Column 1       |     Column 2     |      Column N       |
|---------------------|------------------|---------------------|
|          0.37       |         0.8      |          0.0        |
|---------------------|------------------|---------------------|
|          0.0        |         0.0      |          0.8        |
|---------------------|------------------|---------------------|

生成的数据框应类似于

|---------------------|------------------|---------------------|---------------|
|      Column 1       |     Column 2     |      Column N       |     Sampled   |
|---------------------|------------------|---------------------|---------------|
|          0.37       |         0.8      |          0.0        |       0.8     |
|---------------------|------------------|---------------------|---------------|
|          0.0        |         0.0      |          B          |        B      |
|---------------------|------------------|---------------------|---------------|
|          A          |         5        |          0.8        |        A      |
|---------------------|------------------|---------------------|---------------|

"采样" 列的条目是通过随机选择 "N" 列的相应条目之一来创建的。例如, 从第 2 列、N 列中选择了 "0.8", 依此类推。

df.sample(axis=1)只需选择一列并返回它。这不是我想要的。

实现这一目标的最快方式是什么?该方法需要高效, 因为原始数据框很大, 有大量的行和列。

第1个答案(采用)

熊猫基地 lookup +sample

s=df.columns.to_series().sample(len(df),replace = True)
df['New']=df.lookup(df.index,s)
df
Out[177]:
  Column1  Column2 ColumnN  New
0    0.37      0.8     0.0  0.8
1     0.0      0.0       B    B
2       A      5.0     0.8    A
第2个答案

您可以使用基础 numpy 数组, 并为每行选择一个随机索引。

u = df.values
r = np.random.randint(0, u.shape[1], u.shape[0])

df.assign(Sampled=u[np.arange(u.shape[0]), r])
  Column 1  Column 2 Column N Sampled
0     0.37       0.8      0.0    0.37
1      0.0       0.0        B       B
2        A       5.0      0.8       A
第3个答案
from random import choice
df['sample'] =  df.apply(lambda x:choice(x.values),axis =1)
第4个答案

一个选项是 apply np.random.choice 沿着行到数据框。这可能会也可能不会给你所需要的性能, 但我让你来决定 "

设置: DF 4 列, 11, 000 行

df=pd.DataFrame({'a':[np.random.rand() for i in range(11000)],'b':[np.random.rand() for i in range(11000)],
                 'c':[np.random.rand() for i in range(11000)],'d':[np.random.rand() for i in range(11000)]})

%timeit df['e']=df.apply(lambda x: np.random.choice(x), axis=1)

193 ms ± 28 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

其他基准:

添加 x.values 到 lambda 似乎可以提高大约 20% 的速度。然而, @wen-ben 的解决方案是对同一数据框上的这种方法的 100 倍的改进

1.91 ms ± 155 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

根据要求, 这里是用户 348332.3 的答案的时间, 可能会更好 (我必须做一些事情, 使它与时间魔术, 所以 ymmv)

%%timeit
df1=df.copy()
u = df.values
r = np.random.randint(0, u.shape[1], u.shape[0])

df1=df1.assign(Sampled=u[np.arange(u.shape[0]), r])

590 µs ± 37 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

相关问题

通过随机抽样其他列数据创建新列 如何使用熊猫获得包括每一个组合的计数 如何有效地展开矩阵的值与小块? 如何破坏 Python 对象并释放内存 将具有特殊格式的文本文档转换为熊猫数据框架 用两本字典绘制一只熊猫专栏图