在矢量化循环实现中提高速度和效率

2024-06-28 19:37:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个(7.5MM,17)的数据框,有500k个独特的项目,我正在“去数据透视”,因为没有更好的词:每个独特的项目可以有N个行,这些行与不同的特征相关联,我正在聚合到列中,这样每个独特的项目只有一行

为了做到这一点,我有一个for循环,循环遍历数据帧中的每个唯一项。它将数据帧排序到一个临时数据帧中,该临时数据帧只过滤到由所述唯一项表示的行。然后我申请

df.loc[df['trait']=='xyz'].sum()

对于8个性状,每个性状产生一个聚合变量。然后将这些变量附加到一个临时列表(内部循环)中,该临时列表又附加到输出列表(外部循环)中

在每个循环的末尾,基本dataframe将删除与唯一项相关的所有行,这样随着输出列表的增长,基本dataframe的存储大小将减小(因子~15)

我希望它运行得非常快,据我所知,for循环内部的操作是一个矢量化的实现。然而,一个小时后它只穿过了约7000排。这将运行时期望值设置为不到3天。我可以接受这一点,但我希望能找到更有效的解决方案

我运行这个的机器有32GB的RAM,5TB的存储空间。这个程序只占用大约5GB的内存。有没有一种方法可以使用更多的内存,但移动速度更快

任何见解都将不胜感激

编辑-

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)


Tags: 数据none列表ifislocsumlit
1条回答
网友
1楼 · 发布于 2024-06-28 19:37:07

实际上,您是按“WON”分组的“LIT”,并总结'LIC'&;'问'

下面是一个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使用是一个问题,那么可以看看dask项目,它可以使用类似pandas的API处理内存不足的计算

我会给你指出:

相关问题 更多 >