根据同一数据框中的其他行从数据框中删除行

时间:2019-10-14 16:21:28

标签: pandas dataframe

我有一个看起来像这样的数据框:

     date    | test_hour
------------+-----------
 2000-01-01 |         1
 2000-01-01 |         2
 2000-01-01 |         3
 2000-01-02 |         1
 2000-01-02 |         2
 2000-01-02 |         3
 2000-01-02 |         4
 2000-01-03 |         1
 2000-01-03 |         2

我需要删除所有缺少test_hours = 1、2和3的日期。因此,结果数据框不应包含带有2000-01-03的行,因为它缺少test_hour = 3:

     date    | test_hour
------------+-----------
 2000-01-01 |         1
 2000-01-01 |         2
 2000-01-01 |         3
 2000-01-02 |         1
 2000-01-02 |         2
 2000-01-02 |         3
 2000-01-02 |         4

我目前正在使用for循环来确定要删除的日期,但这似乎违反了使用数据框的目的。有什么更有效的方法可以做到这一点?

3 个答案:

答案 0 :(得分:2)

这是将filterisinall一起使用的一种方式

df.groupby('date').filter(lambda x : pd.Series([1,2,3]).isin(x['test_hour']).all())
         date  test_hour
0  2000-01-01          1
1  2000-01-01          2
2  2000-01-01          3
3  2000-01-02          1
4  2000-01-02          2
5  2000-01-02          3
6  2000-01-02          4

答案 1 :(得分:1)

transformlambda

df[df.groupby('date').test_hour.transform(lambda x: {1, 2, 3} <= {*x})]

理解和map

df[df.date.map({k: {1, 2, 3} <= {*x} for k, x in df.groupby('date').test_hour})]

map的深奥版本

df[[*map({k: {1, 2, 3} <= {*x} for k, x in df.groupby('date').test_hour}.get, df.date)]]

所有产量

         date  test_hour
0  2000-01-01          1
1  2000-01-01          2
2  2000-01-01          3
3  2000-01-02          1
4  2000-01-02          2
5  2000-01-02          3
6  2000-01-02          4

答案 2 :(得分:0)

使用pandas-sets库(https://github.com/Florents-Tselai/pandas-sets)和transform,您可以得到易于阅读的解决方案:

import pandas_sets
import pandas as pd


df = pd.DataFrame({
        'date': ['2000-01-01', '2000-01-01', '2000-01-01', '2000-01-01', '2000-01-02'],
        'test_hour': [1, 2, 3, 4, 1]
        })

df = df[df.groupby('date').transform(set)['test_hour'].set.issuperset({1,2,3})]