如何按索引和列值筛选数据框

5

I have 2 dataframes like this:

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; 
2个回答

2
想法是使用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行)时,它没有过滤所有内容。我认为这是因为存在具有相同“day”值的行。 - daragh
1
@daragh - 添加了另一种解决方案。 - jezrael

1

您可以做的一件事是在两个数据框上设置双重索引并使用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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接