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

  显示原文与译文双语对照的内容

我想通过从剩余列中随机取样来创建一个新的列。

考虑一个带有"n"列的dataframe,如下所示:


|---------------------|------------------|---------------------|


| Column 1 | Column 2 | Column N |


|---------------------|------------------|---------------------|


| 0.37 | 0.8 | 0.0 |


|---------------------|------------------|---------------------|


| 0.0 | 0.0 | 0.8 |


|---------------------|------------------|---------------------|



生成的dataframe应该看起来像


|---------------------|------------------|---------------------|---------------|


| 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的列。"b"中选择了" 0.8",等等。

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

什么是最快的实现这个目标的方法? 方法需要高效,因为原始dataframe具有大量的行和列。

时间:

Pandas 基 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



你可以使用基础 numpy array,并在每行中选择一个随机索引。


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




from random import choice


df['sample'] = df.apply(lambda x:choice(x.values),axis =1)



一个选项是 applynp.random.choice 到 dataframe,沿着行。 这可能会给你所需要的性能,但我将它的留给你决定

设置:4列,11000行


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's 解决方案在同一dataframe上对这里方法进行了 100-fold 改进


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



按照请求,这是user3483203的回答时间,可以能更好( 我必须做一些事情,使它处理时间魔术) 。


%%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)



...