如何使用 Python 和 Pandas 从日期字段按月分组?
How can I group by month from a date field using Python and Pandas?
我有一个数据框,df,如下:
| date | Revenue |
|-----------|---------|
| 6/2/2017 | 100 |
| 5/23/2017 | 200 |
| 5/20/2017 | 300 |
| 6/22/2017 | 400 |
| 6/21/2017 | 500 |
我需要按月对以上数据进行分组以获得输出:
| date | SUM(Revenue) |
|------|--------------|
| May | 500 |
| June | 1000 |
我试过这段代码,但没有用:
df.groupby(month('date')).agg({'Revenue': 'sum'})
我只想使用 Pandas 或 NumPy,不使用其他库。
尝试使用 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
试试这个:
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
对于行数较多的DataFrame,使用strftime
会占用较多的时间。如果日期列已经有datetime64[ns]
的dtype(可以用pd.to_datetime()
转换,或者csv导入时指定parse_dates
等),直接访问datetime属性即可groupby
个标签(方法 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
方法一:strftime
%timeit -n 10 -r 7 T.groupby(T['date'].dt.strftime('%B'))['revenue'].sum()
每个循环 1.47 秒 ± 10.1 毫秒(7 次运行的平均值 ± 标准差,每次 10 次循环)
方法二:石斑鱼
%timeit -n 10 -r 7 T.groupby(pd.Grouper(key='date', freq='1M')).sum()
#NOTE Manually map months as integer {01..12} to strings
每个循环 56.9 毫秒 ± 2.88 毫秒(7 次运行的平均值 ± 标准偏差,每次 10 次循环)
方法三:日期时间属性
%timeit -n 10 -r 7 T.groupby(T['date'].dt.month)['revenue'].sum()
#NOTE Manually map months as integer {01..12} to strings
每个循环 34 毫秒 ± 3.34 毫秒(7 次运行的平均值 ± 标准偏差,每次 10 次循环)
这样效果会更好。
试试这个:
# Explicitly convert to date
df['Date'] = pd.to_datetime(df['Date'])
# Set your date column as index
df.set_index('Date',inplace=True)
# For monthly use 'M', If needed for other freq you can change.
df[revenue].resample('M').sum()
此代码给出与第一个 post 上的 相同的结果。
但问题是我们可以在上述代码中执行更多操作。
推荐使用这个:
>>> df['Date'] = pd.to_datetime(df['Date'])
>>> df.set_index('Date',inplace=True)
>>> df['withdrawal'].resample('M').sum().sort_values()
Date
2019-10-31 28710.00
2019-04-30 31437.00
2019-07-31 39728.00
2019-11-30 40121.00
2019-05-31 46495.00
2020-02-29 57751.10
2019-12-31 72469.13
2020-01-31 76115.78
2019-06-30 76947.00
2019-09-30 79847.04
2020-03-31 97920.18
2019-08-31 205279.45
Name: withdrawal, dtype: float64
其中 做同样的事情。
>>> df.groupby(df['Date'].dt.strftime('%B'))['withdrawal'].sum().sort_values()
Date
October 28710.00
April 31437.00
July 39728.00
November 40121.00
May 46495.00
February 57751.10
December 72469.13
January 76115.78
June 76947.00
September 79847.04
March 97920.18
August 205279.45
Name: withdrawal, dtype: float64
试试这个:
将日期列更改为日期时间格式。
---> df['Date'] = pd.to_datetime(df['Date'])
在数据框中插入一个新行,其月份为 [May, 'June']
---> df['months'] = df['date'].apply(lambda x:x.strftime('%B'))
---> 这里的 x 是取自数据框中日期列的日期。
现在汇总月份列中的聚合数据并对收入求和。
--->response_data_frame = df.groupby('months')['Revenue'].sum()
---->print(response_data_frame)
输出:
month
Revenue
May
500
June
1000
df['Month'] = pd.DatetimeIndex(df['date']).month_name()
使用这个你应该得到
date
Revenue
Month
6/2/2017
100
June
5/23/2017
200
May
5/20/2017
300
May
6/22/2017
400
June
6/21/2017
500
June
我有一个数据框,df,如下:
| date | Revenue |
|-----------|---------|
| 6/2/2017 | 100 |
| 5/23/2017 | 200 |
| 5/20/2017 | 300 |
| 6/22/2017 | 400 |
| 6/21/2017 | 500 |
我需要按月对以上数据进行分组以获得输出:
| date | SUM(Revenue) |
|------|--------------|
| May | 500 |
| June | 1000 |
我试过这段代码,但没有用:
df.groupby(month('date')).agg({'Revenue': 'sum'})
我只想使用 Pandas 或 NumPy,不使用其他库。
尝试使用 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
试试这个:
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
对于行数较多的DataFrame,使用strftime
会占用较多的时间。如果日期列已经有datetime64[ns]
的dtype(可以用pd.to_datetime()
转换,或者csv导入时指定parse_dates
等),直接访问datetime属性即可groupby
个标签(方法 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
方法一:strftime
%timeit -n 10 -r 7 T.groupby(T['date'].dt.strftime('%B'))['revenue'].sum()
每个循环 1.47 秒 ± 10.1 毫秒(7 次运行的平均值 ± 标准差,每次 10 次循环)
方法二:石斑鱼
%timeit -n 10 -r 7 T.groupby(pd.Grouper(key='date', freq='1M')).sum()
#NOTE Manually map months as integer {01..12} to strings
每个循环 56.9 毫秒 ± 2.88 毫秒(7 次运行的平均值 ± 标准偏差,每次 10 次循环)
方法三:日期时间属性
%timeit -n 10 -r 7 T.groupby(T['date'].dt.month)['revenue'].sum()
#NOTE Manually map months as integer {01..12} to strings
每个循环 34 毫秒 ± 3.34 毫秒(7 次运行的平均值 ± 标准偏差,每次 10 次循环)
这样效果会更好。
试试这个:
# Explicitly convert to date
df['Date'] = pd.to_datetime(df['Date'])
# Set your date column as index
df.set_index('Date',inplace=True)
# For monthly use 'M', If needed for other freq you can change.
df[revenue].resample('M').sum()
此代码给出与第一个 post 上的
但问题是我们可以在上述代码中执行更多操作。
推荐使用这个:
>>> df['Date'] = pd.to_datetime(df['Date'])
>>> df.set_index('Date',inplace=True)
>>> df['withdrawal'].resample('M').sum().sort_values()
Date
2019-10-31 28710.00
2019-04-30 31437.00
2019-07-31 39728.00
2019-11-30 40121.00
2019-05-31 46495.00
2020-02-29 57751.10
2019-12-31 72469.13
2020-01-31 76115.78
2019-06-30 76947.00
2019-09-30 79847.04
2020-03-31 97920.18
2019-08-31 205279.45
Name: withdrawal, dtype: float64
其中
>>> df.groupby(df['Date'].dt.strftime('%B'))['withdrawal'].sum().sort_values()
Date
October 28710.00
April 31437.00
July 39728.00
November 40121.00
May 46495.00
February 57751.10
December 72469.13
January 76115.78
June 76947.00
September 79847.04
March 97920.18
August 205279.45
Name: withdrawal, dtype: float64
试试这个:
将日期列更改为日期时间格式。
--->
df['Date'] = pd.to_datetime(df['Date'])
在数据框中插入一个新行,其月份为 [May, 'June']
--->
df['months'] = df['date'].apply(lambda x:x.strftime('%B'))
---> 这里的 x 是取自数据框中日期列的日期。
现在汇总月份列中的聚合数据并对收入求和。
--->
response_data_frame = df.groupby('months')['Revenue'].sum()
---->
print(response_data_frame)
输出:
month | Revenue |
---|---|
May | 500 |
June | 1000 |
df['Month'] = pd.DatetimeIndex(df['date']).month_name()
使用这个你应该得到
date | Revenue | Month |
---|---|---|
6/2/2017 | 100 | June |
5/23/2017 | 200 | May |
5/20/2017 | 300 | May |
6/22/2017 | 400 | June |
6/21/2017 | 500 | June |