Pandas PerformanceWarning:DataFrame 高度碎片化。有效的解决方案是什么?

plo*_*fat 6 insert concatenation pandas

这是代表我的脚本中发生的情况的通用代码:

import pandas as pd
import numpy as np

dic = {}

for i in np.arange(0,10):
    dic[str(i)] = df = pd.DataFrame(np.random.randint(0,1000,size=(5000, 20)), 
                                    columns=list('ABCDEFGHIJKLMNOPQRST'))
    
df_out = pd.DataFrame(index = df.index)

for i in np.arange(0,10):
    df_out['A_'+str(i)] = dic[str(i)]['A'].astype('int')
    df_out['D_'+str(i)] = dic[str(i)]['D'].astype('int')
    df_out['H_'+str(i)] = dic[str(i)]['H'].astype('int')
    df_out['I_'+str(i)] = dic[str(i)]['I'].astype('int')
    df_out['M_'+str(i)] = dic[str(i)]['M'].astype('int')
    df_out['O_'+str(i)] = dic[str(i)]['O'].astype('int')
    df_out['Q_'+str(i)] = dic[str(i)]['Q'].astype('int')
    df_out['R_'+str(i)] = dic[str(i)]['R'].astype('int')
    df_out['S_'+str(i)] = dic[str(i)]['S'].astype('int')
    df_out['T_'+str(i)] = dic[str(i)]['T'].astype('int')
    df_out['C_'+str(i)] = dic[str(i)]['C'].astype('int')
Run Code Online (Sandbox Code Playgroud)

您会注意到,一旦插入列的 df_out(输出)数量超过 100,我就会收到以下警告:

性能警告:DataFrame 高度碎片化。这通常是多次调用的结果frame.insert,性能较差。考虑使用 pd.concat 代替

问题是我该如何使用:

pd.concat()
Run Code Online (Sandbox Code Playgroud)

并且仍然有取决于字典键的自定义列名称?

重要提示:我仍然想保留特定的列选择,而不是全部。就像示例中的那样:A、D、H、I 等...

特别编辑(基于 Corralien 的回答)

cols = {'A': 'float',
        'D': 'bool'}

out = pd.DataFrame()
for c, df in dic.items():
    for col, ftype in cols.items():
        out = pd.concat([out,df[[col]].add_suffix(f'_{c}')], 
                        axis=1).astype(ftype)
    
Run Code Online (Sandbox Code Playgroud)

非常感谢您的帮助 !

Cor*_*ien 4

您可以使用以下理解pd.concat

cols = {'A': 'float', 'D': 'bool'}

out = pd.concat([df[cols].astype(cols).add_prefix(f'{k}_')
                    for k, df in dic.items()], axis=1)
print(out)

# Output:
     0_A   0_D    1_A   1_D    2_A   2_D    3_A   3_D
0  116.0  True  396.0  True  944.0  True  398.0  True
1  128.0  True  102.0  True  561.0  True   70.0  True
2  982.0  True  613.0  True  822.0  True  246.0  True
3  830.0  True  366.0  True  861.0  True  906.0  True
4  533.0  True  741.0  True  305.0  True  874.0  True
Run Code Online (Sandbox Code Playgroud)

  • 不是问题。重要的是,即使您最后使用我的解决方案,它也适用于您:-P。哈哈 (2认同)