这似乎是一个以前应该已经问过的问题,但我找不到。以下是我的问题。
数据:
- 一个主list
(长度约为16,000,000),其中包含最多500个项目的子列表str
。
目标:
- 高效地对主列表中的每个子列表进行洗牌。
我已经尝试了直接使用for
-loop、列表推导式、pandas Series.apply()
、pandarallel
和dask
dataframe的.apply()
和.map_partition()
方法。
for
-loop需要大约15分钟。pd.Series.apply()
、dask.series.apply()
和dask.series.map_partition()
都在6分钟左右完成。
我的问题是“我能更快地实现洗牌吗?” 新创建副本或就地洗牌均可接受。
以下是我的尝试:
def normal_shuffle(series):
output = series.tolist()
length = len(output)
for i in range(length):
random.Random().shuffle(output[i])
return output
def shuffle_returned(a_list):
new_list = a_list
random.shuffle(new_list)
return new_list
def shuffle_partition(a_partition):
return a_partition.apply(shuffle_returned)
%time shuffled_for = normal_shuffle(test_series)
%time shuffled_apply = test_series.apply(shuffle_returned)
pandarallel.initialize(progress_bar=False, nb_workers=8)
%time shuffled_parallel_apply = test_series.parallel_apply(shuffle_returned)
test_ddf = ddf.from_pandas(test_series, npartitions=16)
test_ddf = test_ddf.reset_index(drop=True)
shuffled_ddf = test_ddf.apply(shuffle_returned, meta="some_str")
%time shuffled_ddf.persist()
shuffled_by_parttion_ddf = test_ddf.map_partitions(shuffle_partition, meta="productId")
%time shuffled_by_parttion_ddf.persist()
现在我尝试使用dask分布式来查看是否可以将模型训练和数据洗牌错开,以使训练时间和洗牌时间重叠,从而实现更好的总时间效率。
非常感谢您提供任何有关如何使洗牌操作更有效的反馈或建议。
更新:
经过尝试一些建议,我得出了最快的结果,也令人惊讶的是最简单的解决方案!
%time [np.random.shuffle(x) for x in alist]
CPU times: user 23.7 s, sys: 160 ms, total: 23.9 s
Wall time: 23.9 s
似乎单线程 numpy 是解决这个问题的方法!