我知道通常行的复制对于性能而言是可怕的,这就是为什么Stackoverflow上的大多数答案都不能解释如何实际执行此操作但建议更好的替代方案 - 但对于我的用例,我需要实际执行此操作
我有一个包含复制权重的表,
id some_value weight
1 2 5
2 A 2
3 B 1
4 3 3
我需要按重量值重复每一行。想想一个庞大的数据框架。什么是非常高效的方法来实现这一目标?
预期产出:
id some_value weight
1 2 5
1 2 5
1 2 5
1 2 5
1 2 5
2 A 2
2 A 2
3 B 1
4 3 3
4 3 3
4 3 3
答案 0 :(得分:1)
以下是两种方式
1)使用set_index
和repeat
In [1070]: df.set_index(['id', 'some_value'])['weight'].repeat(df['weight']).reset_index()
Out[1070]:
id some_value weight
0 1 2 5
1 1 2 5
2 1 2 5
3 1 2 5
4 1 2 5
5 2 A 2
6 2 A 2
7 3 B 1
8 4 3 3
9 4 3 3
10 4 3 3
2)使用.loc
和.repeat
In [1071]: df.loc[df.index.repeat(df.weight)].reset_index(drop=True)
Out[1071]:
id some_value weight
0 1 2 5
1 1 2 5
2 1 2 5
3 1 2 5
4 1 2 5
5 2 A 2
6 2 A 2
7 3 B 1
8 4 3 3
9 4 3 3
10 4 3 3
详细
In [1072]: df
Out[1072]:
id some_value weight
0 1 2 5
1 2 A 2
2 3 B 1
3 4 3 3
答案 1 :(得分:0)
或许将其视为加权数组:
def weighted_array(arr, weights):
zipped = zip(arr, weights)
weighted_arr = []
for i in zipped:
for j in range(i[1]):
weighted_arr.append(i[0])
return weighted_arr
返回的weighted_arr将每个元素都放在arr中,重复'权重'次数。
答案 2 :(得分:0)
类似于 uncount
中的 tidyr
:
https://tidyr.tidyverse.org/reference/uncount.html
我编写了一个实现此 API 的包 (https://github.com/pwwang/datar):
from datar import f
from datar.tibble import tibble
from datar.tidyr import uncount
df = tibble(
id=range(1,5),
some_value=[2,'A','B',3],
weight=[5,2,1,3]
)
df >> uncount(f.weight, _remove=False)
输出:
id some_value weight
0 1 2 5
0 1 2 5
0 1 2 5
0 1 2 5
0 1 2 5
1 2 A 2
1 2 A 2
2 3 B 1
3 4 3 3
3 4 3 3
3 4 3 3