如何高效快速地在多个数据框列和行中广播

0 投票
1 回答
41 浏览
提问于 2025-04-13 19:42

我有两个数据框(dataframe)。其中一个是参考数据框,它会更新另一个数据框。

这个参考数据框是通过pd.melt处理过的,同时也是我从另一个流程中筛选出来的产品。这个处理过的数据框中有一列是指向另一个数据框的参考ID。我想根据这个参考ID在第二个数据框的多个列和行中进行更新。让我来解释一下:

处理过的数据框(数据框1)如下:

其他列 参考ID 变量
bla 1 ColumnA cat
bla 1 ColumnB mouse
bla 2 ColumnB dog
bla 3 ColumnB dog
bla 3 ColumnC lion
bla 4 ColumnA cat

在第二个数据框中,我想根据第一个处理过的数据框来构建,像这样:

其他列 参考ID ColumnA ColumnB ColumnC
bla 1 cat mouse
bla 2 dog
bla 3 dog lion
bla 4 cat
bla 5
bla 6

正如你所看到的,数据框中的值是根据参考ID和列名填充的。

那么,为什么不把处理过的数据框再转换回正常的大小,然后进行连接呢?我可以这样做,但我觉得这样会增加开销,因为第二个数据框的行数不同,而且性能也是一个因素。我在考虑使用广播(broadcasting),但我无法在不循环的情况下实现。我不想循环,因为这会比较耗时。这是我现在的代码:

refids = melted_df['RefID'].unique()
i = 0
while i<len(refids):
 q = melted_df.query("RefID=="+str(i))
 qcols = q['variable']
 second_df.iloc[refids[i], list(qcols)] = list(q[value])
 i+=1

现在这个方法可以正常工作,但我觉得速度太慢了。想象一下,如果我们有几百万行数据要处理,这样的速度是无法接受的。我尝试过不使用循环,直接将整个参考ID和整个值放进去,但结果不正确。

有没有人有优化的建议?

1 个回答

2

代码

cols = ['other cols', 'RefID']
idx = pd.MultiIndex.from_product([['bla'], range(1, len(df) + 1)], names=cols)

out = (df.pivot(index=cols, columns='variable', values='value')
       .reindex(idx).reset_index().rename_axis(None, axis=1)
)

输出:

  other cols  RefID ColumnA ColumnB ColumnC
0        bla      1     cat   mouse     NaN
1        bla      2     NaN     dog     NaN
2        bla      3     NaN     dog    lion
3        bla      4     cat     NaN     NaN
4        bla      5     NaN     NaN     NaN
5        bla      6     NaN     NaN     NaN

如果你不想在底部产生多余的行,可以使用以下代码:

out2 = (df.pivot(index=cols, columns='variable', values='value')
        .reset_index().rename_axis(None, axis=1)    
)

输出2:

  other cols  RefID ColumnA ColumnB ColumnC
0        bla      1     cat   mouse     NaN
1        bla      2     NaN     dog     NaN
2        bla      3     NaN     dog    lion
3        bla      4     cat     NaN     NaN

示例代码

import pandas as pd
data1 = {'other cols': ['bla', 'bla', 'bla', 'bla', 'bla', 'bla'], 'RefID': [1, 1, 2, 3, 3, 4], 'variable': ['ColumnA', 'ColumnB', 'ColumnB', 'ColumnB', 'ColumnC', 'ColumnA'], 'value': ['cat', 'mouse', 'dog', 'dog', 'lion', 'cat']}
df = pd.DataFrame(data1)

数据框:

  other cols  RefID variable  value
0        bla      1  ColumnA    cat
1        bla      1  ColumnB  mouse
2        bla      2  ColumnB    dog
3        bla      3  ColumnB    dog
4        bla      3  ColumnC   lion
5        bla      4  ColumnA    cat

撰写回答