我有一个看起来像这样的数据框:
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循环来确定要删除的日期,但这似乎违反了使用数据框的目的。有什么更有效的方法可以做到这一点?
答案 0 :(得分:2)
这是将filter
与isin
和all
一起使用的一种方式
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)
transform
和lambda
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})]