Найти соответствующие значения в двух DataFrames - PullRequest
0 голосов
/ 16 октября 2019

Я должен найти соответствующие значения в двух 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()



Работает, но очень неэффективно, входные кадры (df1, df2) имеютоколо 2 миллионов строк. Кто-нибудь знает более эффективный способ, который встроен в структуру Pandas?

Приветствия.

1 Ответ

1 голос
/ 16 октября 2019

Вы можете достичь этого, сначала 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...