似乎以前应该已经问过一个问题,但我找不到。这样就可以了。
数据:
-主list
(长度为== 16,000,000)的str
子列表(每个子列表最多可包含500个项目)
目标:
-有效地调整主列表中的每个子列表。
我尝试了直接的 for
循环,列表理解,熊猫Series.apply()
,pandarallel
和dask
数据帧{{1} }和.apply()
方法。
.map_partition()
循环大约需要 15分钟。
for
,pd.series.apply()
和dask.series.apply()
都能做到这一点刚过 6分钟。
我的问题是“我能否更快地完成改组”?产生新副本或改组都可以接受。
以下是我的尝试:
dask.series.map_partition()
现在,我尝试使用dask分布式来查看,如果我能以某种方式错开模型训练和数据混排,以使训练时间和混排时间重叠,并获得更好的总体时间效率。
非常感谢任何关于如何使改组操作更有效的反馈或建议。
更新
尝试了一些建议后,以下事实证明是我可以实现的最快的方法,而且也非常简单!
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()
单线程numpy似乎是要走的路!
答案 0 :(得分:2)
@TerryH-您根本不需要
.shuffle()
RAM存储器内容,它足以生成一个aListOfSTRINGs
,所以创建临时文件,但每个列表的费用为np.random.permutation( len( aListOfListsOfSTRINGs[ ith ] ) )
〜O(1)
,花费了ALAP,一个新的随机订单,大小可间接访问ith-260 [us]
的{{1}}成员。
(为什么移动RAM-I / O昂贵的数据以便“读取”-以后在某个地方按顺序排序时,无需再触摸数据,直到ALAP使用组件的间接寻址从缓存服务的块“读取”?)
对于平行 的愿望的实际成本,您可能会喜欢this的帖子,并带有互动式图形工具。
正如下面的@user2357112 supports Monica所述,
改组的目的是在内部 str
, 而不是 在aListOfSTRINGs
上,Mea Culpa
Q :“ 我可以实现改组更快”吗?
是的。很多。 ... aListOfSTRINGs
次-使用合适的工具可以在 aListOfListsOfSTRINGs
下实现 < / em>
Q :“ ... 如何 我可以使其改组操作更有效吗?” >
在普通的Py2.7工具中,就位的 150 x
在2.5 [s]
上花费的少于 .shuffle()
超过16,000,000个项目< / p>
~ 23 [s]
在普通Py3.5工具中,就地{strong> list( L )
在from zmq import Stopwatch; aClk = Stopwatch() #_______________________ a [us] Stopwatch
pass; import random
#_____________L creation ~ 2.7 [s]___________________________________________
aClk.start(); L = [ strID for strID in xrange( int( 16E6 ) ) ]; aClk.stop()
2721084
print L[:5] #___________________________________________________________proof
[0, 1, 2, 3, 4]
#_____________random.shuffle( L )______________________________________+proof
aClk.start(); random.shuffle( L ); aClk.stop(); print "0:5\t", L[:5]
21473261
0:5 [13868243, 13087869, 13207292, 9344202, 1853783]
#_____________random.shuffle( L )______________________________________+proof
aClk.start(); random.shuffle( L ); aClk.stop(); print "0:5\t", L[:5]
22573922
0:5 [837396, 15032889, 10942767, 14571341, 4867854]
#_______________________________________________________________________proof
>>> len( L )
16000000
上的 .shuffle()
下,超过16,000,000个项目。 / p>
~ 48 [s]
list( L )
$ conda activate py3
$ python
...
aClk.start(); L = [ strID for strID in range( int( 16E6 ) ) ]; aClk.stop()
1959052
#_____________random.shuffle( L )______________________________________+proof
aClk.start(); random.shuffle( L ); aClk.stop(); print( "0:5\t", L[:5] )
45104806
0:5 [15744525, 10635923, 14530509, 10535840, 1465987]
#_____________random.shuffle( L )______________________________________+proof
aClk.start(); random.shuffle( L ); aClk.stop(); print( "0:5\t", L[:5] )
47139358
0:5 [884437, 15420153, 9957947, 8118734, 11960914]
数据,仅存储在import numpy as np
#____________L_as_a32______________16E6________________________~ 74 [ms]
>>> aClk.start(); a32 = np.arange( 16E6, dtype = np.int32 ); aClk.stop()
74054
#_____________np.random.shuffle( a32-bit )______________________________+proof
aClk.start(); np.random.shuffle( a32 ); aClk.stop(); print "0:5\t", a32[:5]
2400786
0:5 [ 2487493 14646705 13717283 5602561 7934593]
aClk.start(); np.random.shuffle( a32 ); aClk.stop(); print "0:5\t", a32[:5]
2368381
0:5 [ 4841042 12882529 12298351 2198866 7054284]
aClk.start(); np.random.shuffle( a32 ); aClk.stop(); print "0:5\t", a32[:5]
2369011
0:5 [14595649 7239135 3339593 9517600 6506681]
#_____________np.random.shuffle( a64-bit )______________________________+proof
aClk.start(); np.random.shuffle( a64 ); aClk.stop(); print "0:5\t", a64[:5]
2424487
0:5 [ 3234133 9224551 971604 13027484 806393]
aClk.start(); np.random.shuffle( a64 ); aClk.stop(); print "0:5\t", a64[:5]
2386873
0:5 [ 3212124 10644428 8192909 2234984 13103406]
aClk.start(); np.random.shuffle( a64 ); aClk.stop(); print "0:5\t", a64[:5]
2376065
0:5 [ 5624301 7741070 8859092 12287465 11721315]
str
以不变的成本 aListOfSTRINGs
附加到非重新组合的,线性增长的恒定顺序存储-aListOfSTRINGs
< / li>
O(1)
或aListOfListsOfSTRINGs
数组,只要有新成员aListOfListsOfSTRINGs
进入,只需附加一个aListOfORDINALs
即可) li>
list
,在Py2.7的numpy
下或在Py3.5的len( aListOfListsOfSTRINGs )
下aListOfSTRINGs
-s,以aListOfORDINALs.shuffle()
的代价23 [s]
,以获得实际的< 50 [s]
-s