我需要检查销售数据的两个条件:
- 按年销售
- 在特定天数销售,金额为>0
Dataframe df:
date | id | qual | amount
2020-09-01 | 123 | A | 100
2020-09-02 | 123 | A | 0
2020-09-03 | 123 | A | 90
2020-09-04 | 123 | A | 80
2020-09-01 | 123 | B | 8
2020-09-02 | 123 | B | 6
2020-09-03 | 123 | B | 4
2020-09-04 | 123 | B | 2
2021-02-01 | 123 | B | 18
2020-02-01 | 456 | A | 96
2021-02-02 | 456 | A | 90
2021-01-01 | 789 | A | 30
2021-01-02 | 789 | A | 31
2021-01-03 | 789 | A | 32
2021-01-04 | 789 | A | 29
数据帧有10_000个ID,每个ID有~1000个日期,每个ID有1或2个质量(质量)级别。
需要对ID +质量级别的每个组合执行检查。
在我检查每个ID + Qual之后,我想过滤我的数据帧,以便它只包含通过该检查的ID + Qual组合。
ID: 123 with quality: A
- 有2020年和2021年的销售❌
- 至少有4行,数量为>0❌
- →未通过
ID: 123 with quality: B
- 有2020年和2021年的销售✅
- 至少有4行,数量为>0✅
- →并通过
ID: 456 with quality: A
- 有2020年和2021年的销售✅
- 至少有4行,数量为>0❌
- →未通过
ID: 789 with quality: A
- 有2020年和2021年的销售❌
- 至少有4行,数量为>0✅
- →未通过
结果应该像这样:
date | id | qual | amount
2020-09-01 | 123 | B | 8
2020-09-02 | 123 | B | 6
2020-09-03 | 123 | B | 4
2020-09-04 | 123 | B | 2
2021-02-01 | 123 | B | 18
我的代码:
required_sales_years= [2020, 2021]
required_sales_days = 4
has_required_sales = []
for id in df["id"].unique().tolist():
for qual in df["qual"].unique().tolist():
temp = df.query(
"id== @id and qual == @qual and amount > 0"
)
sales_years = temp["date"].dt.year.unique().tolist()
check_sales_year = all(item in sales_years for item in required_sales_years)
check_sales_days = len(temp.index) >= required_sales_days
if check_sales_year and check_sales_days:
has_required_sales.append((id, qual))
我该怎么做?
使用groupby().transform
计算有效销售额:
required_sale_years = [2020, 2021]
required_sales_days = 4
# intermediate variables
df['year'] = df.date.dt.year
df['valid'] = df['year'].isin(required_sales_years) & df['amount'].gt(0)
# groupby
groups = df.groupby(['id','qual'])
has_years = groups['year'].transform(lambda x: set(required_sales_years).issubset(set(x)))
valid_sales = groups['valid'].transform('sum') >= required_sales_days
output = df[has_years & valid_sales]
输出:
date id qual amount year valid
4 2020-09-01 123 B 8 2020 True
5 2020-09-02 123 B 6 2020 True
6 2020-09-03 123 B 4 2020 True
7 2020-09-04 123 B 2 2020 True
8 2021-02-01 123 B 18 2021 True