繁体   English   中英

通过使用日期时间约束计算不同值进行聚合

[英]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  |
+---------+---------+-------+
  1. 我想按DateGroup并 DF2 并计算 DF1 中有多少不同的项目值,如果新合并的 DF 中的日期位于 DF1 的日期时间约束之间,

  2. 而且,根据新合并的 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 DateGroup ,得到我认为是你的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 合并,如果日期满足约束条件,则创建一个为Truevalid_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

最后,您可以将tmp1tmp2合并在一起(并对列重新排序):

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM