изменение кадра данных Pandas при выполнении слияния - PullRequest
4 голосов
/ 26 сентября 2019

У меня есть pandas.DataFrame (df) с некоторыми метаданными, где есть ID, Column и Value, которые я хотел бы объединить с другим df Например:

df_map = pd.DataFrame({"ID" : [3, 7, 17], "Column" : ["A1", "B7", "C17"], 
                       "Value" : ["ValA1", "ValB7", "ValC17"]})

Я хотел бы объединить выше (для лучшего слова) со следующим df, где имена столбцов совпадают с именами строкизаписи в Column выше, а значения строк в ниже df соответствуют значениям из ID строк выше.

df_main = pd.DataFrame({"A1" : [3, 6], "A5" : [5, 10], "B7" : [7, 14] , 
                        "C17" : [17, 34], "C19" : [19, 38] })

Поэтому я бы хотел объединить их в df's таким образом, чтобы я изменил их на основе столбцов Value, добавив их в качестве дополнительных измерений, где ID's match, то есть df_result = combine(df_map, df_main)

Где я в основном ожидаю результат, как указано ниже

df_result = pd.DataFrame({"A1" : [3, 6], "A5" : [5, 10], "B7" : [7, 14] ,
                          "C17" : [17, 34], "C19" : [19, 38], "Value A1" : ["ValA1", None],
                         "Value B7" : ["ValB7", None], "Value C17" : ["ValC17", None ]})

Out[30]:
   A1  A5  B7  C17  C19 Value A1 Value B7 Value C17
0   3   5   7   17   19    ValA1    ValB7    ValC17
1   6  10  14   34   38     None     None      None

Не уверен, что лучший способ сделать это в pandas?

Ответы [ 2 ]

4 голосов
/ 26 сентября 2019

Сначала DataFrame.melt с преобразованным index в столбец, чтобы избежать потери в DataFrame.merge при левом соединении, затем измените форму обратно на DataFrame.set_indexс DataFrame.unstack, удалить только пропущенные столбцы на DataFrame.dropna и последнее выравнивание MultiIndex с map:

df = (df_main.reset_index()
             .melt('index',var_name='Column', value_name='ID')
             .merge(df_map, how='left')
             .set_index(['index', 'Column'])
             .unstack()
             .rename_axis(None)
             .dropna(how='all', axis=1))
df.columns = df.columns.map('_'.join)
print (df)
   ID_A1  ID_A5  ID_B7  ID_C17  ID_C19 Value_A1 Value_B7 Value_C17
0      3      5      7      17      19    ValA1    ValB7    ValC17
1      6     10     14      34      38      NaN      NaN       NaN
1 голос
/ 26 сентября 2019

Альтернативное решение с Series.map и pandas.concat :

df2=pd.concat([df_main.T[key].map(df_map.set_index('ID')['Value']) for key in df_main.index.tolist()],axis=1).T.add_prefix('Value_')
df_main=pd.concat([df_main,df2],axis=1)
df_main.dropna(how='all',axis=1,inplace=True)
print(df_main)

   A3  A5  B7  C17  C19 Value_A3 Value_B7 Value_C17
0   3   5   7   17   19    ValA1    ValB7    ValC17
1   6  10  14   34   38      NaN      NaN       NaN
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...