加速 Pandas DataFrame 分组应用

3

我有以下代码,是在另一篇帖子上找到的(稍作修改)。它的输出效果非常好,符合我的预期。但是我想知道是否有人对于提高速度有什么建议。我正在比较两个数据框,大约有93,000行和110列。groupby需要20分钟才能完成。我尝试想出加速方法,但没有发现任何有效方法。我现在正在努力想想未来如何处理更大的数据量。我也愿意尝试其他方法解决这个问题!

###Function that is called to check values in dataframe groupby     
def report_diff(x):
        return 'SAME' if x[0] == x[1] else '{} | {}'.format(*x)
        #return '' if x[0] == x[1] else '{} | {}'.format(*x)

print("Concatening CSV and XML data together...")
###Concat the dataframes together
df_all = pd.concat(
    [df_csv, df_xml], 
    axis='columns', 
    keys=['df_csv', 'df_xml'],
    join='outer',
)
print("Done")

print("Swapping column levels...")
###Display keys at the top of each column
df_final = df_all.swaplevel(axis='columns')[df_xml.columns[0:]]
print("Done")

df_final = df_final.fillna('None')

print("Grouping data and checking for matches...")
###Apply report_diff function to each row
df_excel = df_final.groupby(level=0, axis=1).apply(lambda frame: frame.apply(report_diff, axis=1))

你能为 df_csvdf_xml 创建一些虚拟数据吗(最好是以字典格式)?我感觉使用向量化操作可以显著提高速度。 - Sven Harris
@SvenHarris 对不起,您能澄清一下吗?您是想看一些虚拟数据吗?这两个变量中的数据分别从CSV和XML文件中读取,然后在这些步骤之前进行了大量处理。 - Chris Brown
3
请提供一个简单的可复现的例子,例如 df_csv = pd.DataFrame({"a":[1,2,3]}),它将有助于理解代码运行方式并验证给出的答案是否返回了预期值。 - Sven Harris
@SvenHarris 希望这对您有所帮助,这是一些示例数据(已修改) df_csv.head(2).to_dict() Out[84]: 'I1SP-1C': {'123456789': '普通股', '987654321': '普通股'}, 'I1SP-1E': {'123456789': '普通股股息', '987654321': '普通股股息'}, 'I1SP-3C': {'123456789': '医疗保健提供商和服务','987654321': '建筑产品'}, 'I1SP-3E': {'123456789': 'BQZJBY4', '987654321': '2268130'}, 'I1SP-3Z': {'123456789': '0', '987654321': '0'}, - Chris Brown
1个回答

1
您可以使用 np.where 函数,检查 df_csv[df_xml.columns] 是否等于 df_xml,如果为 True,则该值为 'SAME',否则您可以像平常一样合并两个数据框中的值。请注意保留 HTML 标签。
df_csv = pd.DataFrame({'a':range(4),'b':[0,0,1,1],'c':list('abcd')})
df_xml = pd.DataFrame({'b':[0,2,3,1],'c':list('bbce')})

方法

df_excel = pd.DataFrame( np.where( df_csv[df_xml.columns] == df_xml, #find where
                                   'SAME', #True
                                   df_csv[df_xml.columns].astype(str) + ' | ' + df_xml.astype(str)), #False
                        columns=df_xml.columns
                        index=df_xml.index)

print (df_excel)
       b      c
0   SAME  a | b
1  0 | 2   SAME
2  1 | 3   SAME
3   SAME  d | e

使用你的方法得到了相同的结果。

这很棒,而且运行得非常好,只是当我这样做时,我会失去我的两个索引列,有没有办法也在这里保留索引列呢? - Chris Brown
1
我在pd.DataFrame代码的末尾添加了"index=df_xml.index",看起来运行良好!这比原始代码快得多!谢谢! - Chris Brown
@ChrisBrown,你说得很好,我没有考虑到它们的重要性。我会编辑我的答案来包括它 :) - Ben.T
所以我在这方面还有一个困境...你有任何想法如何运行像这样具有重复索引值的代码吗?那是否可能呢?当我尝试使用重复索引值运行此代码时,我会收到以下错误:ValueError: Can only compare identically-labeled DataFrame objects。 - Chris Brown
1
太棒了,非常感谢!它很好地起作用了,你真是我的救星! - Chris Brown
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接