#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 здесь отличается от ожидаемого кадра данных в вашем вопросе. Я думаю, что ваш вопрос был не совсем ясен. В любом случае. Я рад, если вы нашли ответ, который хотели.