【问题标题】:Merging 2 pandas DataFrames with certain conditions在某些条件下合并 2 个 pandas DataFrame
【发布时间】:2019-12-24 18:06:16
【问题描述】:

我不知道如何在某些条件下合并 2 个 pandas 数据帧。

我有这个:

import pandas as pd

df1 = pd.DataFrame({'Name': ['A', 'A', 'A', 'B' ,'B' ,'B'],
                    'Date': ['10/15/2019', '10/16/2019', '10/17/2019', '10/15/2019', '10/16/2019', '10/17/2019'], 
                    'Value 1': [101, 102, 103, 201, 202, 203],
                    'Value 2': ['A1', 'A2', 'A3', 'B1', 'B2', 'B3']})

df2 = pd.DataFrame({'Name': ['A', 'A', 'B', 'B' ,'C'],
                    'Date': ['10/14/2019', '10/15/2019', '10/13/2019', '10/18/2019', '10/18/2019'], 
                    'Value 3': [2, 2, 22, 44, 222]})

我需要解决这个问题

我只需要合并 df1 中存在的名称,但添加 df2 中存在的日期。但是,这些日期应早于 2019 年 10 月 13 日。

我能得到的最接近的是

df_m = pd.merge(df1, df2, how='outer', left_on=['Name', 'Date'], right_on=['Name', 'Date'], sort=True)

但这包括所有内容(来自 df2 的“C” - 我不需要它,而日期为 10/13/2019 的“B” - 我也不需要它)。

非常感谢任何帮助。

编辑: 我们可以放弃日期大于 2019 年 10 月 13 日的条件 - 我只是通过创建另一个 df2_mod 来解决这个问题,其中我没有包含我不需要的日期。但是,df2_mod 中存在的某些日期不在 df1 中,我需要将它们与值 3 合并。但是我不需要 df1 中不存在的从 df2 到 df1 的名称

【问题讨论】:

  • 您的要求不清楚。如果您从 df1 和 df2 中获取所有内容,那就是外连接。外连接将始终包含“C”结果,因为它包含来自两个数据帧的所有内容。然后,如果您对日期进行子集 > 2019 年 10 月 13 日,则 C 结果将保留,因为该记录的日期是 10/18。要么你在描述不可能的事情,要么你需要更清楚地重申你的要求。
  • 所以,我需要满足 2 个条件: 1. 合并“外部”,但不包括 df1 中不存在的名称 2. 合并 df2 中的所有日期,即使它们不存在存在于df1中。
  • 我更新了我最初的问题。谢谢。

标签: python python-3.x pandas dataframe merge


【解决方案1】:

这是一种解决方案(如更新后的问题所述,我不会过滤大于 10/13/2019 的日期):

  1. 首先我们过滤 df2 并删除所有在 df1 中不存在的 'Names'
  2. 在名称和日期列上使用 df1df2_filtered 进行外部联接
  3. 对值进行排序并重新创建索引

import pandas as pd

df1 = pd.DataFrame({'Name': ['A', 'A', 'A', 'B' ,'B' ,'B'],
                    'Date': ['10/15/2019', '10/16/2019', '10/17/2019', '10/15/2019', '10/16/2019', '10/17/2019'],
                    'Value 1': [101, 102, 103, 201, 202, 203],
                    'Value 2': ['A1', 'A2', 'A3', 'B1', 'B2', 'B3']})

df2 = pd.DataFrame({'Name': ['A', 'A', 'B', 'B' ,'C'],
                    'Date': ['10/14/2019', '10/15/2019', '10/13/2019', '10/18/2019', '10/18/2019'],
                    'Value 3': [2, 2, 22, 44, 222]})

df2_filtered = df2[df2['Name'].isin(df1['Name'])]       # we want df2 rows with `Names` that exists in df1
print(df1.merge(df2_filtered, on=['Name', 'Date'], how='outer').sort_values(['Name', 'Date']).reset_index(drop=True))

打印:

  Name        Date  Value 1 Value 2  Value 3
0    A  10/14/2019      NaN     NaN      2.0
1    A  10/15/2019    101.0      A1      2.0
2    A  10/16/2019    102.0      A2      NaN
3    A  10/17/2019    103.0      A3      NaN
4    B  10/13/2019      NaN     NaN     22.0
5    B  10/15/2019    201.0      B1      NaN
6    B  10/16/2019    202.0      B2      NaN
7    B  10/17/2019    203.0      B3      NaN
8    B  10/18/2019      NaN     NaN     44.0

【讨论】:

  • 非常感谢,有道理!我赞成答案!这对我帮助很大!
猜你喜欢
  • 2014-09-19
  • 1970-01-01
  • 1970-01-01
  • 2020-08-17
  • 1970-01-01
  • 2017-05-01
  • 2018-07-22
  • 2018-11-25
  • 1970-01-01
相关资源
最近更新 更多