调整 Pandas 数据框架形状时进行合并。

4

我有一个包含一些元数据的 pandas.DataFrame (df),其中有一个 IDColumnValue,我想将它与另一个 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,以便根据ID's匹配的情况下,将Value列作为附加维度添加到重塑后的数据框中。即: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 中做这件事的最佳方法是什么?


["A1", "B7", "C17"] 中有错别字吗?也许正确的是 ["A3", "B7", "C17"] - jezrael
为什么df_map中的列A1被映射到df_main的列A3? - Quang Hoang
啊,抱歉是打错了,谢谢@Jezrael指出,已经修正了! - RK1
2个回答

4

首先使用 DataFrame.melt 将转换后的 index 转换为列以避免在左连接中丢失,在通过 DataFrame.merge 进行合并,然后再通过DataFrame.set_indexDataFrame.unstack进行重塑,再通过DataFrame.dropna删除仅含有缺失值的列,最后通过map展开“MultiIndex”:

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

会是Value_A3吧...不是Value-A1? - ansev
@lostCode - https://dev59.com/2Lbna4cB1Zd3GeqPc48l#58117177?noredirect=1#comment102623558_58117027 - jezrael
@lostcode,你说得对,在输出中将“Value A1”更改为与输入对齐。 - RK1

1

使用Series.mappandas.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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接