合并两个具有共同值的熊猫数据框,这些数据框在一个数据框中显示为列,而在另一个数据框中显示为行

Posted

技术标签:

【中文标题】合并两个具有共同值的熊猫数据框,这些数据框在一个数据框中显示为列,而在另一个数据框中显示为行【英文标题】:Merging two pandas dataframes with common values that are presented in one dataframe as columns and on the other are in rows 【发布时间】:2020-06-14 23:00:02 【问题描述】:

我有一个数据框,其中包含数百列作为客户 ID,其中一行包含每个客户 ID 的票证总数,如下所示: (df1是原始csv文件多次变换的结果)

df1
+-----+----+-----+
| 30  | 5  | 100 |
+-----+----+-----+
| 122 | 40 |  13 |
+-----+----+-----+

另一个数据框有 2 列,一个 account_id 和一个 client_id,如下所示:

df2
+------------+-----------+
| account_id | client_id |
+------------+-----------+
| 4char      | 4         |
+------------+-----------+
| 3char      | 5         |
+------------+-----------+
| 2char      | 30        |
+------------+-----------+
| 16char     | 9         |
+------------+-----------+
| 17char     | 100       |
+------------+-----------+

我想要一个包含 3 列 account_id、client_id 和 total_tickets 的文件,如下所示:

df
+------------+-----------+---------------+
| account_id | client_id | total_tickets |
+------------+-----------+---------------+
| 4char      | 4         | null
+------------+-----------+---------------+
| 3char      | 5         | 40
+------------+-----------+---------------+
| 2char      | 30        | 122
+------------+-----------+---------------+
| 16char     | 9         | null
+------------+-----------+---------------+
| 17char     | 100       | 13
+------------+-----------+---------------+

到目前为止,我已经达到了这一点: 我在两个数据帧上创建了一个 iterrows() 函数,如果在 df1 的列中找到 df2 的 client_id,则使用 isin() 函数检查,接下来我在 df2 上添加一个带有 assign() 函数的新列 total_tickets

f1 = df1, f2 = df2
def populating_df(f1, f2):
    for org_nr in f2.iterrows():
        for col in f1.iterrows():
           matched_org_nr =  f2.client_id.isin(f1.columns)
           if matched_org_nr.any() == True:
               sum_of_tickets_per_col = matched_org_nr
           # create a new column in f2 file with the values of total_tickets for each org number matched
           f2 = f2.loc[:].assign(Total_Tickets=sum_of_tickets_per_col) 
        return f2

结果我得到了这张表:

+------------+-----------+---------------+
| account_id | client_id | total_tickets |
+------------+-----------+---------------+
|  4char     | 4         |False
+------------+-----------+---------------+
|  3char     | 5         | True
+------------+-----------+---------------+
|  2char     | 30        | True
+------------+-----------+---------------+
| 16char     | 9         | False
+------------+-----------+---------------+
| 17char     | 100       | True
+------------+-----------+---------------+

如果有人对如何解决这个问题有任何建议,我会很高兴

【问题讨论】:

对于 df1 是 client_id 标头吗? 是的@Datanovice 【参考方案1】:

您可以使用pd.merge

df = pd.merge(df1, df2, on="client_id", how='outer')

【讨论】:

这行不通你需要在合并之前做一些处理【参考方案2】:

首先我们需要融化 df1 以便您对每一行进行观察

然后您可以使用外部合并以从两列中获取键

df_melt = pd.melt(df1,var_name='client_id',value_name='total_tickets')

df3 = pd.merge(df_melt ,df2,on=['client_id'],how='outer')

#make sure dtypes are the same.

#df_melt ['client_id'] = df_melt ['client_id'].astype(int) 

df3 = df3[["account_id", "client_id", "total_tickets"]].sort_values(
    "account_id", ascending=False
)

print(df3)

     account_id  client_id  total_tickets
3   4char                4            NaN
1   3char                5           40.0
0   2char               30          122.0
2   17char             100           13.0
4   16char               9            NaN

【讨论】:

合并没有发生,给我一个值错误ValueError: You are trying to merge on object and int64 columns. If you wish to proceed you should use pd.concat @Denisa 你看到这条线了吗#df_melt ['client_id'] = df_melt ['client_id'].astype(int) 运行这个然后运行合并我不确定你的列最初是字符串还是整数。 我得到了df_melt的结果,看起来不错,但是合并又出现了关键错误 您能print(df2.dtypes)print(df_melt.dtypes) 并将结果发布到您的主要问题吗? 使用了错误的df,它打印出正确的结果,检查打印df3的最后一步【参考方案3】:

merge 是关键,但您必须先转置初始数据帧,并进行一些外观更改,例如重置其索引并提供相关列名:

转换可能是:

df1.rename(0: 'total_tickets').T.rename_axis('client_id').reset_index()

给予:

   client_index  total_tickets
0            30            122
1             5             40
2           100             13

一旦完成,合并就很简单了:

result = df2.merge(df1.rename(0: 'total_tickets').T.rename_axis('client_id').reset_index(),
                   on='client_id', how='left')

按预期给予:

  account_id  client_id  total_tickets
0      4char          4            NaN
1      3char          5           40.0
2      2char         30          122.0
3     16char          9            NaN
4     17char        100           13.0

【讨论】:

以上是关于合并两个具有共同值的熊猫数据框,这些数据框在一个数据框中显示为列,而在另一个数据框中显示为行的主要内容,如果未能解决你的问题,请参考以下文章

加入两个具有重复值的熊猫数据框[重复]

如何比较两个熊猫数据框并返回将它们相互映射的索引?

具有两个以上数据框的熊猫的外部合并[重复]

合并两个具有相同列名但在熊猫中列数不同的数据框

Excel - 合并具有共同值的行并将差异连接在一列中

删除熊猫数据框中具有特定值的行[重复]