我正在寻找一种过滤DataFrame中的行的方法。我有以下数据:
data = [
{'year':2015, 'v1':'str1', 'v2':'str2', 'v3':'str3', 'val': 6},
{'year':2016, 'v1':'str1', 'v2':'str2', 'v3':'str3', 'val': 5},
{'year':2017, 'v1':'str1', 'v2':'str2', 'v3':'str3', 'val': 3},
{'year':2015, 'v1':'str11', 'v2':'str2', 'v3':'str3', 'val': 4},
{'year':2016, 'v1':'str11', 'v2':'str2', 'v3':'str3', 'val': 9},
{'year':2017, 'v1':'str12', 'v2':'str2', 'v3':'str3', 'val': 1},
{'year':2016, 'v1':'str1', 'v2':'str21', 'v3':'str3', 'val': 9},
{'year':2017, 'v1':'str1', 'v2':'str21', 'v3':'str3', 'val': 7},
{'year':2018, 'v1':'str1', 'v2':'str21', 'v3':'str3', 'val': 8},
{'year':2015, 'v1':'str1', 'v2':'str2', 'v3':'str31', 'val': 6},
{'year':2016, 'v1':'str1', 'v2':'str2', 'v3':'str31', 'val': 5},
{'year':2016, 'v1':'str1', 'v2':'str2', 'v3':'str31', 'val': 6},
{'year':2017, 'v1':'str1', 'v2':'str2', 'v3':'str31', 'val': 3},
{'year':2018, 'v1':'str1', 'v2':'str2', 'v3':'str31', 'val': 4}
]
过滤规则:如果从2015年开始,至少没有连续三年,且在v1,v2和v3中匹配的行,则应删除这些行。从2015年开始,至少应保持在v1,v2和v3中相匹配的行至少三年。
上面的示例经过过滤后的预期输出为:
import pandas as pd
df = pd.DataFrame(data)
# filtering step
print(df)
year v1 v2 v3 val
0 2015 str1 str2 str3 6
1 2016 str1 str2 str3 5
2 2017 str1 str2 str3 3
3 2015 str1 str2 str31 6
4 2016 str1 str2 str31 5
5 2016 str1 str2 str31 6
6 2017 str1 str2 str31 3
7 2018 str1 str2 str31 4
有什么想法吗?
答案 0 :(得分:2)
您可以链接两个groupby
+ filter
v = ['v1', 'v2', 'v3']
(df.groupby(v).filter(lambda s: 2015 in s['year'].values)
.groupby(v).filter(lambda s: s.year.nunique() >= 3) and s.year.diff().isin([0, 1, np.nan]).all())
year v1 v2 v3 val
0 2015 str1 str2 str3 6
1 2016 str1 str2 str3 5
2 2017 str1 str2 str3 3
3 2015 str1 str2 str31 6
4 2016 str1 str2 str31 5
5 2016 str1 str2 str31 6
6 2017 str1 str2 str31 3
7 2018 str1 str2 str31 4
答案 1 :(得分:2)
我觉得我们可以将filter
缩短如下
df.groupby(['v1','v2','v3']).filter(lambda x : pd.Series([2015,2016,2017]).isin(x['year']).all())
Out[142]:
year v1 v2 v3 val
0 2015 str1 str2 str3 6
1 2016 str1 str2 str3 5
2 2017 str1 str2 str3 3
9 2015 str1 str2 str31 6
10 2016 str1 str2 str31 5
11 2016 str1 str2 str31 6
12 2017 str1 str2 str31 3
13 2018 str1 str2 str31 4