我必须在两个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框架中构建更有效的方法吗?
干杯。
答案 0 :(得分:1)
您可以通过首先merging
通过相应列的数据帧,然后将GroupBy
与named_aggregations
(pandas >= 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
如果要将列保留为信息,只需使用merge
和GroupBy.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