【问题标题】:Compare two dataframes and delete not same dates比较两个数据框并删除不同的日期
【发布时间】:2017-12-07 18:24:45
【问题描述】:

我有两个数据框,想比较它们并删除 df2 中与 df1 中不同的天数。我尝试使用:

df2[~df2.Date.isin(df1.Date)]

但这不起作用并得到一个空的数据框。 df2 应该看起来像 df1。数据框如下所示:

df1
        Date
0    20-12-16
1    21-12-16
2    22-12-16
3    23-12-16
4    27-12-16
5    28-12-16
6    29-12-16
7    30-12-16
8    02-01-17
9    03-01-17
10   04-01-17
11   05-01-17
12   06-01-17

df2

         Date
0    20-12-16
1    21-12-16
2    22-12-16
3    23-12-16
4    24-12-16
5    25-12-16
6    26-12-16
7    27-12-16
8    28-12-16
9    29-12-16
10   30-12-16
11   31-12-16
12   01-01-17
13   02-01-17
14   03-01-17
15   04-01-17
16   05-01-17
17   06-01-17

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    似乎dtypes 不同。比较需要相同。

    检查方式:

    print (df1.Date.dtype)
    print (df2.Date.dtype)
    

    然后根据需要进行转换:

    df1['Date'] = pd.to_datetime(df1['Date'])
    df2['Date'] = pd.to_datetime(df2['Date'])
    

    我添加了另外 2 个解决方案 - 第一个是 numpy.in1d,第二个是 merge,因为需要默认的内部连接:

     df = df2[np.in1d(df2.Date, df1.Date)]
    print (df)
             Date
    0  2016-12-20
    1  2016-12-21
    2  2016-12-22
    3  2016-12-23
    7  2016-12-27
    8  2016-12-28
    9  2016-12-29
    10 2016-12-30
    13 2017-01-02
    14 2017-01-03
    15 2017-01-04
    16 2017-01-05
    17 2017-01-06
    

    df = df1.merge(df2, on='Date')
    print (df)
             Date
    0  2016-12-20
    1  2016-12-21
    2  2016-12-22
    3  2016-12-23
    7  2016-12-27
    8  2016-12-28
    9  2016-12-29
    10 2016-12-30
    13 2017-01-02
    14 2017-01-03
    15 2017-01-04
    16 2017-01-05
    17 2017-01-06
    

    示例:

    d1 = {'Date': ['20-12-16', '21-12-16', '22-12-16', '23-12-16', '27-12-16', '28-12-16', '29-12-16', '30-12-16', '02-01-17', '03-01-17', '04-01-17', '05-01-17', '06-01-17']}
    d2 = {'Date': ['20-12-16', '21-12-16', '22-12-16', '23-12-16', '24-12-16', '25-12-16', '26-12-16', '27-12-16', '28-12-16', '29-12-16', '30-12-16', '31-12-16', '01-01-17', '02-01-17', '03-01-17', '04-01-17', '05-01-17', '06-01-17']}
    df1 = pd.DataFrame(d1)
    df2 = pd.DataFrame(d2)
    

    print (df1.Date.dtype)
    object
    
    print (df2.Date.dtype)
    object
    
    df1['Date'] = pd.to_datetime(df1['Date'], format='%d-%m-%y')
    df2['Date'] = pd.to_datetime(df2['Date'], format='%d-%m-%y')
    

    【讨论】:

    • 非常感谢您的回答。当使用 print 我收到一个对象时,转换有助于将其转换为 datetime64[ns]。当尝试比较数据帧时,我仍然收到一个空数据帧。此外,我想要相等的日期而不是不相等的日期。
    • 非常感谢。它似乎有效,但在比较 df1 和 df2 时,我收到的输出应该与 df1 的日期相同。清楚吗?我不确定自己做错了什么或误解了什么?
    • @MCM - 你的样品也有问题吗?你的熊猫版本是什么? print (pd.show_versions()).
    • 我使用的版本是pandas:0.20.2。你为什么要剥皮?
    • 嗯,我也有。我的样本数据也有问题?
    【解决方案2】:

    你的错误来自逻辑。您要选择 df1 的 df2 日期。所以你应该写

    df2[df2.Date.isin(df1.Date)]
    

    与 df1 中的比较/包含为真的布尔值相反

    您也可以使用

    获得相同的结果
    set(b.Date)-(set(b.Date)-set(a.Date))
    

    然后应该通过以下方式使用:

    pd.DataFrame(sorted((set(b.Date)-(set(b.Date)-set(a.Date)))), columns=["Date"] )   
    

    虽然排序不是最优的,但您可以通过更好的逻辑在 pandas 中更改它。

     df = pd.DataFrame(list((set(b.Date)-(set(b.Date)-set(a.Date)))), columns=["Date"] ) 
     df.Date = [date.date() for date in df.Date]
    

    或 df.Date.dt.date

    (见How do I convert dates in a Pandas data frame to a 'date' data type?

    【讨论】:

    • 非常感谢。我不想要不同的日期,而是比较两个数据框 df1 和 df2 并从 df2 中删除不相等的日期并将其放入新的数据框中。是不是更清楚了?
    • 是的。所以这正是我的回答。 df2.Date.isin(df1.Date) 返回一个布尔值,其中 True 代表 df2 的日期,类似于 df1。所以你直接将这些布尔索引到 df2 中。
    • 所以上面的答案有帮助。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 2020-03-15
    • 2018-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多