[英]Aggregate by counting the distinct value with datetime constraint
我有两个 python pandas 数据帧,简化形式如下所示:
DF1
+---------+---------+------+-------+
| Date_in | Date_out| Group| Item |
+---------+---------+------+-------+
| 1991-08 | 2000-08 | A | A1 |
| 1991-08 | 2021-02 | A | A2 |
| 1997-02 | 2021-02 | B | B1 |
| 1998-03 | 2001-03 | C | C1 |
| 1999-02 | 2002-02 | D | D1 |
| 2000-09 | 2021-02 | D | D2 |
| 2000-03 | 2001-04 | D | D3 |
| 2001-08 | 2021-02 | D | D4 |
+---------+---------+------+-------+
DF2
+---------+---------+-------+
| Date | Group | Item |
+---------+---------+-------+
| 2000-06 | A | A1 |
| 2000-06 | A | A1 |
| 2000-07 | A | A1 |
| 2000-07 | A | A1 |
| 2000-07 | A | A2 |
| 2000-07 | B | B1 |
| 2000-08 | D | D3 |
| 2000-08 | D | D4 |
| 2001-05 | D | D1 |
| 2001-05 | D | D2 |
| 2001-05 | D | D3 |
| 2002-04 | D | D2 |
| 2002-04 | D | D2 |
+---------+---------+-------+
我想按Date
和Group
并 DF2 并计算 DF1 中有多少不同的项目值,如果新合并的 DF 中的日期位于 DF1 的日期时间约束之间,
而且,根据新合并的 DF 中的日期时间约束存在多少不同的项目(我认为它已由 @Rick_M 的回答解决)
所需 output
+---------+---------+------------------------+-----------------------+
| Date | Group | Total_item_1 | Total_item_2 |
+---------+---------+------------------------+-----------------------+
| 2000-06 | A | 2 | 1 |
| 2000-07 | A | 1 | 1 |
| 2000-07 | B | 1 | 1 |
| 2000-08 | C | 1 | 0 |
| 2000-08 | D | 3 | 2 |
| 2001-05 | D | 3 | 3 |
| 2002-04 | D | 2 | 1 |
+---------+---------+------------------------+-----------------------+
感谢任何评论和反馈,希望我能更清楚地表达这个想法
我仍然不太确定我是否理解您的问题,因为我没有重现相同的“所需输出”(上面可能有错误吗?),但即使没有,我希望这仍然对您有所帮助。
您的数据:
df1 = pd.DataFrame.from_records([('1991-08', '2000-08', 'A', 'A1'), ('1991-08', '2021-02', 'A', 'A2'),
('1997-02', '2021-02', 'B', 'B1'), ('1998-03', '2001-03', 'C', 'C1'),
('1999-02', '2002-02', 'D', 'D1'), ('2000-09', '2021-02', 'D', 'D2'),
('2000-03', '2001-04', 'D', 'D3'), ('2001-08', '2021-02', 'D', 'D4')], columns=['Date_in','Date_out','Group','Item'])
df2 = pd.DataFrame.from_records([('2000-06', 'A', 'A1'), ('2000-06', 'A', 'A1'),
('2000-07', 'A', 'A1'), ('2000-07', 'A', 'A1'),
('2000-07', 'A', 'A2'), ('2000-07', 'B', 'B1'),
('2000-08', 'D', 'D3'), ('2000-08', 'D', 'D4'),
('2001-05', 'D', 'D1'), ('2001-05', 'D', 'D2'),
('2001-05', 'D', 'D3'), ('2002-04', 'D', 'D2'),
('2002-04', 'D', 'D2')], columns=['Date','Group','Item'])
将字段更改为日期时间类型:
df1['Date_in'] = pd.to_datetime(df1['Date_in'], format="%Y-%m")
df1['Date_out'] = pd.to_datetime(df1['Date_out'], format="%Y-%m")
df2['Date'] = pd.to_datetime(df2['Date'], format="%Y-%m")
我们可以立即从 df2 中删除重复项:
df2 = df2.drop_duplicates().copy()
...然后 groupby Date
和Group
,得到我认为是你的Total_item_2
列:
tmp1 = df2.groupby(['Date','Group']).nunique().rename(columns={'Item':'Total_item_2'}).reset_index()
print(tmp1)
Date Group Total_item_2
0 2000-06-01 A 1
1 2000-07-01 A 2
2 2000-07-01 B 1
3 2000-08-01 D 2
4 2001-05-01 D 3
5 2002-04-01 D 1
对于下一部分,我将留下各种中间步骤,以便您检查正在发生的事情。 如果您愿意,您可以组合其中的一些步骤。
将df1
与这个新结果 dataframe 合并,如果日期满足约束条件,则创建一个为True
的valid_date
列:
tmp = pd.merge(df1, tmp1[['Date','Group']], on='Group', suffixes=['_1','_2'], how='left')
tmp['valid_date'] = (tmp['Date']>=tmp['Date_in']) & (tmp['Date']<=tmp['Date_out'])
然后只使用具有有效日期的行,并执行与我们之前所做的类似的 groupby :
tmp2 = tmp[tmp['valid_date']].groupby(['Date','Group'])['Item'].nunique().reset_index().rename(columns={'Item':'Total_item_1'})
print(tmp2)
Date Group Total_item_1
0 2000-06-01 A 2
1 2000-07-01 A 2
2 2000-07-01 B 1
3 2000-08-01 D 2
4 2001-05-01 D 2
5 2002-04-01 D 2
最后,您可以将tmp1
和tmp2
合并在一起(并对列重新排序):
result = pd.merge(tmp1, tmp2, on=['Date', 'Group'])
result = result[['Date','Group','Total_item_1','Total_item_2']]
print(result)
Date Group Total_item_1 Total_item_2
0 2000-06-01 A 2 1
1 2000-07-01 A 2 2
2 2000-07-01 B 1 1
3 2000-08-01 D 2 2
4 2001-05-01 D 2 3
5 2002-04-01 D 2 1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.