附加具有多列索引和重叠列名的数据帧

2024-09-28 16:19:44 发布

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

我有多个在循环的不同迭代中生成的数据帧,如下所示: d1在迭代1中创建,d2在迭代2中创建,依此类推。。你知道吗

d1=pd.DataFrame({'PARTICIPANT_ID':['idA'],'AGE':[32],'GENDER':['male'],'colA':[20],'colB':[100]})
d2=pd.DataFrame({'PARTICIPANT_ID':['idA'],'AGE':[32],'GENDER':['male'],'colC':[1],'colD':[6]})
d3=pd.DataFrame({'PARTICIPANT_ID':['idA'],'AGE':[32],'GENDER':['male'],'colE':[60],'colF':[11]})
d4=pd.DataFrame({'PARTICIPANT_ID':['idB'],'AGE':[43],'GENDER':['female'],'colA':[30],'colB':[200]})
d5=pd.DataFrame({'PARTICIPANT_ID':['idB'],'AGE':[43],'GENDER':['female'],'colC':[2],'colD':[7]})
d6=pd.DataFrame({'PARTICIPANT_ID':['idB'],'AGE':[43],'GENDER':['female'],'colE':[70],'colF':[12]})
d7=pd.DataFrame({'PARTICIPANT_ID':['idC'],'AGE':[28],'GENDER':['female'],'colE':[56],'colF':[48]})

我希望在每次迭代后继续将这些数据帧合并到更大的最终数据帧,或者将它们存储为字典或其他数据类型,并在循环结束时将它们合并在一起。你知道吗

这就是输出所需要的样子(参与者ID本身就可以作为这些数据帧的索引):

PARTICIPANT_ID  AGE GENDER  colA    colB    colC    colD    colE    colF
idA             32  male    20.0    100.0   1.0     6.0     60      11
idB             43  female  30.0    200.0   2.0     7.0     70      12
idC             28  female  NaN     NaN     NaN     NaN     56      48

我现在做的是:

df_final = df_final.set_index(['PARTICIPANT_ID','AGE','GENDER'],inplace=True).combine_first(d1.set_index(['PARTICIPANT_ID','AGE','GENDER'],inplace=True))

其中df_final是最终的输出数据帧,我在循环中为每个迭代中生成的新数据帧重复这个过程。你知道吗

这种类型的合并的问题是速度非常慢。有没有人能提出一个更好的方法,以更快更有效的方式实现同样的产出。你知道吗

请注意,循环迭代了几十万条记录,并且比上面的示例中显示的列多得多。你知道吗


Tags: 数据iddataframeagenangendermalefemale
1条回答
网友
1楼 · 发布于 2024-09-28 16:19:44

您可以通过concat+groupby+first获得相同的逻辑,也许对实际数据来说更快:

df_res = (pd.concat([d1, d2, d3, d4, d5, d6, d7], sort=False)
              .groupby(['PARTICIPANT_ID', 'AGE', 'GENDER']).first())
#                           colA   colB  colC  colD  colE  colF
#PARTICIPANT_ID AGE GENDER                                     
#idA            32  male    20.0  100.0   1.0   6.0  60.0  11.0
#idB            43  female  30.0  200.0   2.0   7.0  70.0  12.0
#idC            28  female   NaN    NaN   NaN   NaN  56.0  48.0

否则,我会说reduce,但你似乎已经这么做了:

from functools import reduce

reduce(lambda l,r: l.combine_first(r), 
       [x.set_index(['PARTICIPANT_ID', 'AGE', 'GENDER']) for x in [d1, d2, d3, d4, d5, d6, d7]])

myl = [d1, d2, d3, d4, d5, d6, d7]

%timeit pd.concat(myl, sort=False).groupby(['PARTICIPANT_ID', 'AGE', 'GENDER']).first()
#9.11 ms ± 310 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit reduce(lambda l,r: l.combine_first(r), [x.set_index(['PARTICIPANT_ID', 'AGE', 'GENDER']) for x in myl])
#61.3 ms ± 1.18 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

相关问题 更多 >