我想通过从剩余列中随机抽取数据来创建一个新列。
考虑具有“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 |
|---------------------|------------------|---------------------|---------------|
“Sampled”列的条目是通过随机选择“N”列的相应条目之一来创建的。例如,从列2中选择“0.8”,从列N中选择“B”,依此类推。
df.sample(axis=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
您可以使用底层的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
from random import choice
df['sample'] = df.apply(lambda x:choice(x.values),axis =1)
一种选择是apply
np.random.choice
沿着行到数据帧。这可能会或可能不会为您提供所需的性能,但我会由您决定
设置:DF有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的解决方案在同一数据帧上对此方法进行了100倍的改进
1.91 ms ± 155 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
根据要求,这是用户3483203的答案的时机,可能会更好(我不得不做一些事情来使它与时间魔法一起工作,所以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)