如何使用Python/Pandas从Date字段按月分组

Sym*_*ony 13 python pandas pandas-groupby

我有一个数据帧df,如下所示:

| date      | Revenue |
|-----------|---------|
| 6/2/2017  | 100     |
| 5/23/2017 | 200     |
| 5/20/2017 | 300     |
| 6/22/2017 | 400     |
| 6/21/2017 | 500     |
Run Code Online (Sandbox Code Playgroud)

我需要按月对上述数据进行分组,以获得输出:

| date | SUM(Revenue) |
|------|--------------|
| May  | 500          |
| June | 1000         |
Run Code Online (Sandbox Code Playgroud)

我试过这段代码,但它不起作用:

df.groupby(month('date')).agg({'Revenue': 'sum'})
Run Code Online (Sandbox Code Playgroud)

我想只使用Pandas或Numpy而不使用其他库

shi*_*vsn 25

试试这个:

In [6]: df['date'] = pd.to_datetime(df['date'])

In [7]: df
Out[7]: 
        date  Revenue
0 2017-06-02      100
1 2017-05-23      200
2 2017-05-20      300
3 2017-06-22      400
4 2017-06-21      500



In [59]: df.groupby(df['date'].dt.strftime('%B'))['Revenue'].sum().sort_values()
Out[59]: 
date
May      500
June    1000
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考,这为日期提供了 ua 字符串列,它既没有性能也没有用(作为真正的重新采样/时间分组) (2认同)

qbz*_*ker 16

尝试使用pandas Grouper进行分组:

df = pd.DataFrame({'date':['6/2/2017','5/23/2017','5/20/2017','6/22/2017','6/21/2017'],'Revenue':[100,200,300,400,500]})
df.date = pd.to_datetime(df.date)
dg = df.groupby(pd.Grouper(key='date', freq='1M')).sum() # groupby each 1 month
dg.index = dg.index.strftime('%B')

     Revenue
 May    500
June    1000
Run Code Online (Sandbox Code Playgroud)

  • 如果您的日期跨年,则此方法不起作用。然后,每月将不再只有一行(例如上面的五月和六月),而是每年有多个五月和六月。 (2认同)

yon*_*123 5

对于具有许多行的DataFrame,使用strftime会占用更多时间。如果date列已具有dtype datetime64[ns](可以用于pd.to_datetime()转换或parse_dates在csv导入期间指定,等等),则可以直接访问groupby标签的datetime属性(方法3)。加速是巨大的。

import numpy as np
import pandas as pd

T = pd.date_range(pd.Timestamp(0), pd.Timestamp.now()).to_frame(index=False)
T = pd.concat([T for i in range(1,10)])
T['revenue'] = pd.Series(np.random.randint(1000, size=T.shape[0]))
T.columns.values[0] = 'date'

print(T.shape) #(159336, 2)
print(T.dtypes) #date: datetime64[ns], revenue: int32
Run Code Online (Sandbox Code Playgroud)

方法1:strftime

%timeit -n 10 -r 7 T.groupby(T['date'].dt.strftime('%B'))['revenue'].sum()
Run Code Online (Sandbox Code Playgroud)

每个循环1.47 s±10.1毫秒(平均±标准偏差,共运行7次,每个循环10个)

方法2:石斑鱼

%timeit -n 10 -r 7 T.groupby(pd.Grouper(key='date', freq='1M')).sum()
#NOTE Manually map months as integer {01..12} to strings
Run Code Online (Sandbox Code Playgroud)

每个循环56.9 ms±2.88 ms(平均±标准偏差。运行7次,每个循环10个)

方法3:日期时间属性

%timeit -n 10 -r 7 T.groupby(T['date'].dt.month)['revenue'].sum()
#NOTE Manually map months as integer {01..12} to strings
Run Code Online (Sandbox Code Playgroud)

每个循环34毫秒±3.34毫秒(平均±标准偏差,共运行7次,每个循环10个循环)

  • 请注意,如果您拥有超过一年的数据,则方法1和3会汇总它们,而方法2则不会。同样,方法1的结果按字母顺序排序。 (3认同)