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