在两个DataFrame中找到相应的值

时间:2019-10-16 11:42:19

标签: python pandas dataframe

我必须在两个Pandas DataFrame中找到相应的值。

输入: df1:

   server    system     directions msgTYPE    msgID      count
0     1       sys1_in       in      ADT       MSG0001      1
1     1       sys1_in       in      ADT       MSG0002      1
2     1       sys1_in       in      ADT       MSG0003      1
3     1       sys1_in       in      ADT       MSG0004      1

df2:

   server    system     directions  msgTYPE     msgID      count
0     1       sys2_out       out      ADT       MSG0001      1
1     1       sys2_out       out      ADT       MSG0001      1
2     1       sys3_out       out      ADT       MSG0003      1
3     1       sys4_out       out      ADT       MSG0004      1

输出应该是:

     system_in       system_out        count
0     sys1_in         sys2_out           2
1     sys1_in         sys3_out           1
2     sys1_in         sys4_out           1


因此,我必须从两个DF构建一个df,其中包含具有进出系统的列,并且其中的mesgID是相关的。

我正在通过df.itertuples和df.goupby来实现:

model = pd.DataFrame(columns=['in', 'out', 'count'])
for item in ins.itertuples(index=True, name='Pandas'):
        selected = outs.query('msgID == "%s"' % (getattr(item, "msgID")))
        for row in selected.itertuples(index=True, name='Pandas2'):
            model = model.append({'in': getattr(item, "system"), 'out': getattr(row, "system"), 'count': 1},
                                 ignore_index=True)
result = model.groupby(['in', 'out'])['count'].sum().reset_index()



它可以工作,但是效率极低,输入Frames(df1,df2)大约有200万行。有人知道在Pandas框架中构建更有效的方法吗?

干杯。

1 个答案:

答案 0 :(得分:1)

您可以通过首先merging通过相应列的数据帧,然后将GroupBynamed_aggregationspandas >= 0.25.0中的新功能)使用来实现此目的:

columns = [col for col in df1.columns if col != 'system']

mrg = df1.merge(df2, on=columns, suffixes=['_in', '_out'])

mrg.groupby(columns).agg(
    system_in=('system_in', 'first'),
    system_out=('system_out', 'first'),
    count=('system_in', 'size')
).reset_index(drop=True)

输出

  system_in system_out  count
0   sys1_in   sys2_out      2
1   sys1_in   sys3_out      1
2   sys1_in   sys4_out      1

如果要将列保留为信息,只需使用mergeGroupBy.count

df1.merge(df2, on=columns, suffixes=['_in', '_out'])\
   .groupby(columns, as_index=False).count()

输出

   server directions msgTYPE    msgID  count  system_in  system_out
0       1         in     ADT  MSG0001      1          2           2
1       1         in     ADT  MSG0003      1          1           1
2       1         in     ADT  MSG0004      1          1           1