【问题标题】:Avoid duplicate columns while merging with pandas与 pandas 合并时避免重复列
【发布时间】:2020-02-26 22:07:48
【问题描述】:

我有几十个数据框想要与“参考”数据框合并。我想在两个数据框中都存在列时合并它们,或者相反,当它们不存在时创建一个新列。我觉得这与topic 密切相关,但我无法弄清楚它是否适用于我的情况。 另外请注意,用于合并的键从不包含重复项。

# Reference dataframe
df = pd.DataFrame({'date_time':['2018-06-01 00:00:00','2018-06-01 00:30:00','2018-06-01 01:00:00','2018-06-01 01:30:00']})

# Dataframes to merge to reference dataframe
df1 = pd.DataFrame({'date_time':['2018-06-01 00:30:00','2018-06-01 01:00:00'],
                'potato':[13,21]})

df2 = pd.DataFrame({'date_time':['2018-06-01 01:30:00','2018-06-01 02:00:00','2018-06-01 02:30:00'],
                'carrot':[14,8,32]})

df3 = pd.DataFrame({'date_time':['2018-06-01 01:30:00','2018-06-01 02:00:00'],
                'potato':[27,31]})


df = df.merge(df1, how='left', on='date_time')
df = df.merge(df2, how='left', on='date_time')
df = df.merge(df3, how='left', on='date_time')

结果是:

              date_time  potato_x  carrot  potato_y
0  2018-06-01 00:00:00       NaN     NaN       NaN
1  2018-06-01 00:30:00      13.0     NaN       NaN
2  2018-06-01 01:00:00      21.0     NaN       NaN
3  2018-06-01 01:30:00       NaN    14.0      27.0 

虽然我想:

              date_time  potato  carrot 
0  2018-06-01 00:00:00       NaN     NaN  
1  2018-06-01 00:30:00      13.0     NaN   
2  2018-06-01 01:00:00      21.0     NaN 
3  2018-06-01 01:30:00      27.0    14.0 

编辑(按照@sammywemmy 的回答): 在导入它们之前,我不知道数据框列的名称是什么(在循环中)。通常,与我的参考数据框合并的数据框包含大约 100 列,其中 90%-95% 与其他数据框通用。

【问题讨论】:

  • 所以最终的数据框将有大约 100 列?
  • 每个要合并的新数据框包含大约 100 列。在这 100 列中,可能有 10 列的名称在以前的数据框中不存在。所以,假设我想合并 15 个数据框,最后我将有 100 列 + 15*10 = 250 列
  • 其他列似乎是食物名称(马铃薯,胡萝卜,...),通用键是 date_time。 100 列很多,我不知道如何跟踪。我建议您编写融合每个数据帧的代码,使用 date_time 作为 index_var,然后执行合并。

标签: python-3.x pandas


【解决方案1】:

我会 pd.concat 类似的结构化数据框,然后 merge 其他像这样:

df.merge(pd.concat([df1, df3]), on='date_time', how='left')\
  .merge(df2, on='date_time', how='left')

输出:

             date_time  potato  carrot
0  2018-06-01 00:00:00     NaN     NaN
1  2018-06-01 00:30:00    13.0     NaN
2  2018-06-01 01:00:00    21.0     NaN
3  2018-06-01 01:30:00    27.0    14.0

以下每厘米:

df = pd.DataFrame({'date_time':['2018-06-01 00:00:00','2018-06-01 00:30:00','2018-06-01 01:00:00','2018-06-01 01:30:00']})

# Dataframes to merge to reference dataframe
df1 = pd.DataFrame({'date_time':['2018-06-01 00:30:00','2018-06-01 01:00:00'],
                'potato':[13,21]})

df2 = pd.DataFrame({'date_time':['2018-06-01 01:30:00','2018-06-01 02:00:00','2018-06-01 02:30:00'],
                'carrot':[14,8,32]})

df3 = pd.DataFrame({'date_time':['2018-06-01 01:30:00', '2018-06-01 02:00:00'],'potato':[27,31], 'zucchini':[11,1]})

df.merge(pd.concat([df1, df3]), on='date_time', how='left').merge(df2, on='date_time', how='left')

输出:

             date_time  potato  zucchini  carrot
0  2018-06-01 00:00:00     NaN       NaN     NaN
1  2018-06-01 00:30:00    13.0       NaN     NaN
2  2018-06-01 01:00:00    21.0       NaN     NaN
3  2018-06-01 01:30:00    27.0      11.0    14.0

【讨论】:

  • 我认为您的解决方案只有在合并/连接的数据框与 df 完全相似或不同时才有效。例如,我不知道如何处理数据框,例如:df3 = pd.DataFrame({'date_time':['2018-06-01 01:30:00', '2018-06-01 02:00:00'],'potato':[27,31], 'zucchini':[11,1]})
【解决方案2】:

从您的代码继续,
使用filter方法提取与土豆相关的列,
沿列轴对它们求和,
并删除包含土豆_的列...

df['potato'] = df.filter(like='potato').fillna(0).sum(axis=1)

exclude_columns = df.columns.str.contains('potato_[a-z]')
df = df.loc[:,~exclude_columns]

    date_time         carrot    potato
0   2018-06-01 00:00:00 NaN     0.0
1   2018-06-01 00:30:00 NaN     13.0
2   2018-06-01 01:00:00 NaN     21.0
3   2018-06-01 01:30:00 14.0    27.0

【讨论】:

  • 在导入之前我不知道列名是什么。更准确地说,每个新数据帧都包含大约 100 列,其中 90%-95% 与其他数据帧相同。我编辑了我的问题以添加这些信息。
猜你喜欢
  • 1970-01-01
  • 2020-11-30
  • 2017-03-13
  • 2013-10-08
  • 2018-09-18
  • 2018-09-01
  • 1970-01-01
  • 2020-06-10
  • 2018-06-13
相关资源
最近更新 更多