如何按日期和度量字段分组以计算排名?

时间:2019-12-05 12:04:35

标签: python pandas pandas-groupby

我有一个包含学生姓名,交易日期和金额的数据集。 每个学生进行了多次交易。

我想根据每个学生的总人数来计算当月排名和上个月排名。

我可以按学生姓名分组,以使用以下方式计算每个学生的总金额:

transactions['Totals'] = transactions.groupby('Student Name')['Sale Amount'].transform('sum')

如何将其扩展为两个不同的列,以计算每个学生的上个月总计和当月总计,以便为他们分配上个月和当月排名?

日期采用以下格式:

    09/05/2015 04:18 PM
    07/15/2019 09:50 AM
    05/18/2018 02:34 PM
    08/11/2018 06:29 PM
    06/14/2018 07:42 AM

编辑:添加数据框以供参考:

Out[15]: 
      Date of Transaction       Student Name  Sale Amount
0     09/05/2015 04:18 PM          Dan Kelly         4333
1     07/15/2019 09:50 AM         Peter Dyer         8805
2     05/18/2018 02:34 PM  Natalie Robertson         5640
3     08/11/2018 06:29 PM        Sean Miller         6485
4     06/14/2018 07:42 AM     Thomas Forsyth         6815
                  ...                ...          ...
9977  03/15/2018 09:28 PM        Grace Vance         6379
9978  08/07/2019 11:14 PM  Alexandra Cameron         6688
9979  01/09/2015 10:53 AM  Sebastian Vaughan         2262
9980  05/19/2019 10:00 PM     Caroline Blake         6977
9981  01/11/2016 04:05 AM     Austin Edmunds         3205

[9982 rows x 3 columns]

编辑:添加示例预期输出:

enter image description here

1 个答案:

答案 0 :(得分:2)

我创建了一个数据框,其中包含您所知的最少数据:“学生姓名”,“销售金额”,“日期”

我的数据框:

          df = pd.DataFrame([['12/05/2019 04:18 PM','Marisa',500],
               ['11/29/2019 04:18 PM','Marisa',500],
               ['11/20/2019 04:18 PM','Marisa',800],
               ['12/04/2019 04:18 PM','Peter',300],
               ['11/30/2019 04:18 PM','Peter',300],
               ['12/05/2019 04:18 PM','Debra',400],
               ['11/28/2019 04:18 PM','Debra',200],
               ['11/15/2019 04:18 PM','Debra',600],
               ['10/23/2019 04:18 PM','Debra',200]],columns=['Date','Student Name','Sale Amount']
               )

确保日期是日期时间列。

df.Date = pd.to_datetime(df.Date)

这将为您提供原始数据框中每个学生每月的总金额:

df['Total'] = df.groupby(['Student Name',pd.Grouper(key='Date', freq='1M')])['Sale Amount'].transform('sum')


    Date Student             Name       Sale Amount  Total
0 2019-12-05 16:18:00       Marisa          500      500
1 2019-11-29 16:18:00       Marisa          500     1300
2 2019-11-20 16:18:00       Marisa          800     1300
3 2019-12-04 16:18:00        Peter          300      300
4 2019-11-30 16:18:00        Peter          300      300
5 2019-12-05 16:18:00        Debra          400      400
6 2019-11-28 16:18:00        Debra          200      800
7 2019-11-15 16:18:00        Debra          600      800
8 2019-10-23 16:18:00        Debra          200      200

如何仅打印所选结果?

df现在是dnew:

dnew = df

让日期删除时间仅保留几个月:

#Strip date to month
dnew['Date'] = dnew['Date'].apply(lambda x:x.date().strftime('%m'))

“销售金额”条目和按学生姓名和日期分组(新数据框为“销售”):

#Drop Sale Amount 
sales = dnew.drop(['Sale Amount'], axis=1).groupby(['Student Name','Date'])['Total'].max()


print(sales)
Student Name  Date
Debra         10       200
              11       800
              12       400
Marisa        11      1300
              12       500
Peter         11       300
              12       300

实际上,“销售”是pandas.core.series.Series,了解这一点很重要

print(sales.index)
MultiIndex([( 'Debra', '10'),
        ( 'Debra', '11'),
        ( 'Debra', '12'),
        ('Marisa', '11'),
        ('Marisa', '12'),
        ( 'Peter', '11'),
        ( 'Peter', '12')],
       names=['Student Name', 'Date'])    

 from datetime import datetime      
 curMonth = int(datetime.today().strftime('%m')) #transform to integer to perform (curMonth-1)
 #12

 #months of interest
 moi = sales.iloc[(sales.index.get_level_values('Date') == str(curMonth-1)) | (sales.index.get_level_values('Date') == str(curMonth))]

 print(moi)

 Student Name  Date
 Debra         11       800
               12       400
 Marisa        11      1300
               12       500
 Peter         11       300
               12       300