【问题标题】:How to filter dataframe on index AND column value如何过滤索引和列值的数据框
【发布时间】:2019-10-26 21:28:14
【问题描述】:

我有 2 个这样的数据框:

df1

             sales    day    ...
    index    
    1001     567      321
    1002     600      1530
    1005     789      998
    1008     825      775
    1002     300      1120

df2

             sales    day    ...
    index    
    1001     567      321
    1002     600      1530
    1005     789      998
    1014     620      1000
    1008     825      775
    1009     589      1100
    1002     300      1120
    1005     770      400
    1008     820      1600        

我只想在 df2 中保留索引和日期值与 df1 完全相同的行

所以结果应该是:

df2

             sales    day    ...
    index    
    1001     567      321
    1002     600      1530
    1005     789      998
    1008     825      775
    1002     300      1120

我不能使用下面的 isin 函数,因为 df2 中有一些行具有相同的索引但不同的日期值。唯一的就是索引和日期的组合。

    df2 = df2[df2.index.isin(df1.index)]

基本上我想在 SQL 中做的是

    select *
    from   table1 t1,
           table2 t2,
    where  t1.id = t2.id
    and    t1.day = t2.day; 

【问题讨论】:

    标签: python pandas dataframe filter


    【解决方案1】:

    想法是通过DataFrame.set_index 使用append 参数创建MultiIndex,因此可以通过Index.isin 进行过滤:

    df = df2[df2.set_index('day', append=True).index.isin(df1.set_index('day', append=True).index)]
    print (df)
           sales   day
    index             
    1001     567   321
    1002     600  1530
    1005     789   998
    1008     825   775
    1002     300  1120
    

    替代merge:

    df = (df1.reset_index()
             .merge(df2.reset_index(), on=['day','index'], suffixes=('_',''))
             .set_index('index')[df2.columns])
    print (df)
           sales   day
    index             
    1001     567   321
    1002     600  1530
    1005     789   998
    1008     825   775
    1002     300  1120
    

    【讨论】:

    • 看起来该解决方案正在处理我在此处包含的受限数据帧,但是当应用于全尺寸数据帧(20k 行和 40k 行)时,它并没有过滤所有数据。我认为这是因为有些行具有相同的“天”值
    • @daragh - 添加了替代解决方案
    【解决方案2】:

    您可以做的一件事是在两个数据帧上设置双索引并使用 loc 访问:

    df1 = df1.reset_index().set_index(['index','day'])
    df2 = df2.reset_index().set_index(['index','day'])
    
    print(df2.loc[df1.index])
    

    输出(如果你不想要双索引,你可以做reset_index(level=1)

                sales
    index day        
    1001  321     567
    1002  1530    600
    1005  998     789
    1008  775     825
    1002  1120    300
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-27
      • 1970-01-01
      • 2022-06-20
      • 1970-01-01
      • 2015-05-28
      • 2019-04-28
      相关资源
      最近更新 更多