В результате слияния двух фреймов данных со значениями агрегированных столбцов

#pandas #dataframe #numpy #group-by #pandas-groupby

Вопрос:

Фрейм данных 1

{‘идентификатор’: [1, 2, 3], ‘отдел’: [101, 102, 103]}

 id dept .... 1 101 ....  2 102 .... 3 103 ....  

Фрейм данных 2

{‘идентификатор’: [1, 1, 5], ‘регион 1’: [‘CUD’, ‘DAS’, ‘ITF’], регион 2′: [‘IOP’, ‘POL’, ‘IJK’]}

 id region1 region2 ... 1 CUD IOP ... 1 DAS POL ... 5 ITF IJK ...  

Результирующий фрейм данных должен быть следующим

 id dept concatinated 1 101 [{region1: 'CUD', region2: 'IOP'},{region1: 'DAS', region2: 'POL', ...}] 2 102 [] 3 103 [] null null [{region1: 'ITF'}, {region2: 'IJK'}, ...]  

Примечание: Столбцы фреймов данных 1 и 2 являются динамическими ожидаемыми идентификаторами (может иметь N столбцов) Есть ли какой-либо способ достичь этого результата с помощью панд или NumPy!!! (Оптимизированные решения заметны)

Ответ №1:

Мое решение кажется немного сложным, я не уверен, что есть простой способ сделать это.

 import pandas as pd import numpy as np df1 = pd.DataFrame({'id': [1, 2, 3 ,2 ,6], 'dept': [101, 102, 103 ,104,106]}) df2 = pd.DataFrame({'id': [1, 1, 5, 7], 'region1': ['CUD', 'DAS', 'ITF', "CUD"], 'region2': ['IOP', 'POL', 'IJK',"IOP"]})  df=df1.merge(df2,how="outer") df["concatinated"] = df.apply(lambda x:{"region1":x.region1,"region2":x.region2},axis=1) df=df.groupby(["id","dept"],dropna=False).apply(lambda x:[i for i in x.concatinated if pd.notna(i["region1"])]).reset_index() df=df[(~df.id.duplicated()) | (df['id'].isnull())] df.loc[~df.id.isin(df1.id),"id"] = np.nan df=df.rename(columns={0:"concatinated"}) df  
 id dept concatinated 0 1.0 101.0 [{'region1': 'CUD', 'region2': 'IOP'}, {'regio... 1 2.0 102.0 [] 3 3.0 103.0 [] 4 NaN NaN [{'region1': 'ITF', 'region2': 'IJK'}] 5 6.0 106.0 [] 6 NaN NaN [{'region1': 'CUD', 'region2': 'IOP'}]  

Комментарии:

1. Да, это было немного сложно. добавляя еще одно условие, что делать, если я не знаю столбцов второго фрейма данных, например, я не могу сказать, что это всегда будет регион 1 и регион 2…

2. Я обновил свой ответ, проверьте это !

3. Ваш код добавит только столбцы region1 и region2, df1 и df2 могут содержать N столбцов, я не могу добавить все имена столбцов в код, верно?

4. Я расширил ваши данные примера и обновил свой код еще раз, попробуйте еще раз, пожалуйста !

5. Я действительно ценю ваш ответ, спасибо за это, но df["concatinated"] = df.apply(lambda x:{"region1":x.region1,"region2":x.region2},axis=1) у меня 75 столбцов в моем исходном df2, поэтому я не могу добавить имена всех столбцов, которые вы указали как region1, region2. и у меня 136 столбцов в моем 1-м кадре данных, я не могу сгруппировать их все df=df.groupby(["id","dept"],dropna=False) так.

Ответ №2:

 df2['region_comb'] = df2.apply(lambda row: {col: row[col] for col in df2.columns}, axis=1, result_type='reduce') df2 = df2.groupby('fid')['region_comb'].apply(list).reset_index(name='merged') result_df = pd.merge(df2, df1, left_on='fid', right_on='fid', how='outer')  

решения работают!!!

Комментарии:

1. result_df здесь отличается от ожидаемого кадра данных в вашем вопросе. Я думаю, что ваш вопрос был не совсем ясен. В любом случае. Я рад, если вы нашли ответ, который хотели.