Python 在矢量化循环实现中提高速度和效率
我有一个(7.5MM,17)数据框,其中包含500k个唯一项,我正在“反透视”,因为没有更好的词:每个唯一项可以有N个跨各种特征关联的行,我将这些行聚合到列中,以便每个唯一项只有一行 为了做到这一点,我有一个for循环迭代数据帧中的每个唯一项。它将数据帧排序为一个临时数据帧,该临时数据帧只过滤由所述唯一项表示的行。然后我申请Python 在矢量化循环实现中提高速度和效率,python,pandas,dataframe,for-loop,Python,Pandas,Dataframe,For Loop,我有一个(7.5MM,17)数据框,其中包含500k个唯一项,我正在“反透视”,因为没有更好的词:每个唯一项可以有N个跨各种特征关联的行,我将这些行聚合到列中,以便每个唯一项只有一行 为了做到这一点,我有一个for循环迭代数据帧中的每个唯一项。它将数据帧排序为一个临时数据帧,该临时数据帧只过滤由所述唯一项表示的行。然后我申请 df.loc[df['trait']=='xyz'].sum() 对于8个性状,每个性状产生一个聚合变量。然后将这些变量附加到临时列表(循环内部)中,该临时列表又附加到输
df.loc[df['trait']=='xyz'].sum()
对于8个性状,每个性状产生一个聚合变量。然后将这些变量附加到临时列表(循环内部)中,该临时列表又附加到输出列表(循环外部)中
在每个循环结束时,基本数据帧将删除与唯一项相关的所有行,例如,随着输出列表的增长,基本数据帧的存储大小将减小(系数~15)
我希望它运行得非常快,就我所知,for循环内部的操作是一个矢量化的实现。然而,一个小时后,它只通过了约7000行。这将运行时预期设置为不到3天。我可以接受这一点,但我希望能找到更有效的解决方案
我正在运行此操作的机器具有32GB RAM、.5TB存储空间。该程序仅占用约5GB的RAM。有没有一种方法可以使用更多的内存,但移动速度更快
任何洞察都将不胜感激
编辑-
wolst = []
cnt = 0
for i in wodf['WON'].unique().tolist():
tlst = []
wo = i
tdf = wodf.loc[wodf['WON']==i]
matsum = tdf.loc[tdf['LIT']=="M",'LIC'].sum()
labsum = tdf.loc[tdf['LIT']=="L", 'LIC'].sum()
labhrs = tdf.loc[tdf['LIT']=="L", 'Q'].sum()
tcsum = tdf.loc[tdf['LIT']=="T", 'LIC'].sum()
numtrp = tdf.loc[tdf['LIT']=="T", 'Q'].sum()
pmusum = tdf.loc[tdf['LIT']=="PM", 'LIC'].sum()
prtsum = tdf.loc[tdf['LIT']=="P", 'LIC'].sum()
stdsum = tdf.loc[tdf['LIT']=="S", 'LIC'].sum()
stdhrs = tdf.loc[tdf['LIT']=="S", 'Q'].sum()
labsum = labsum+stdsum
labhrs = labhrs+stdhrs
if labsum is None:
labsum = 0
if labhrs is None:
labhrs = 0
if matsum is None:
matsum=0
if tcsum is None:
tcsum=0
if numtrp is None:
numtrp=0
if pmusum is None:
pmusum=0
if prtsum is None:
prtsum=0
tlst.append([wo,labsum,labhrs,matsum,tcsum,numtrp,pmusum,prtsum])
wolst.append(tlst)
print(cnt)
cnt+=1
其中,
wodf
为(7.5MM,17)您基本上是按照“赢”和“亮”进行分组,并对“LIC”和“Q”进行汇总
下面是一个groupby可以做类似事情的示例
In [42]: df = pd.DataFrame({'WON' : ['foo', 'bar', 'foo', 'bar',
...: ...: 'foo', 'bar', 'foo', 'foo'],
...: ...: 'LIT' : ['one', 'one', 'two', 'three',
...: ...: 'two', 'two', 'one', 'three'],
...: ...: 'LIC' : np.random.randn(8),
...: ...: 'Q' : np.random.randn(8)})
In [43]: df
Out[43]:
WON LIT LIC Q
0 foo one 0.148776 1.963984
1 bar one 0.008530 -0.494986
2 foo two 0.218419 0.384919
3 bar three 0.944845 -0.185242
4 foo two 0.218473 1.505220
5 bar two 0.669328 0.146424
6 foo one -0.861758 0.482464
7 foo three -0.627680 1.604041
In [44]: df.groupby(['WON', 'LIT'])['LIC', 'Q'].sum().unstack()
Out[44]:
LIC Q
LIT one three two one three two
WON
bar 0.008530 0.944845 0.669328 -0.494986 -0.185242 0.146424
foo -0.712981 -0.627680 0.436891 2.446449 1.604041 1.890139
In [45]: df.groupby(['WON', 'LIT'])['LIC', 'Q'].sum()
Out[45]:
LIC Q
WON LIT
bar one 0.008530 -0.494986
three 0.944845 -0.185242
two 0.669328 0.146424
foo one -0.712981 2.446449
three -0.627680 1.604041
two 0.436891 1.890139
如果RAM使用是一个问题,您可以看看这个项目,它可以使用类似熊猫的API处理内存不足的计算
我想指出:
- 韦斯·麦金尼(《熊猫》一书的作者)
groupby
完成的事情,缺少for
循环opportunity@roganjosh添加了代码示例,Thinkings?@lexual nevermind,我将数组作为单个项目列表传递。这是工作顺利!注意,在调试时,我建议您针对数据集的精简版本运行代码,以便它在几秒钟内运行。e、 g.df_测试=df.iloc[:100000]