如何高效快速地在多个数据框列和行中广播
我有两个数据框(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