看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
pandas.Grouper 是专门用来生成分组依据的工具,可以按列、按索引、按计算结果、时序中的频率等内容为依据进行分组。pandas.Grouper() 是 pandas 提供的一个工具,用于在进行分组操作时,指定如何对 DataFrame 或 Series 进行分组。它常用于按时间、频率或某些自定义条件对数据进行分组。Grouper 可以与 groupby() 函数结合使用,以便更灵活地控制分组操作。
pandas.Grouper()
可以用于时间序列数据、具有多级索引的 DataFrame
或 Series
,以及任何需要自定义分组的情况。它主要用于在 DataFrame
或 Series
上定义分组的规则。
pandas.Grouper(
key=None,
level=None,
freq=None,
axis=0,
sort=False,
closed=None,
label=None,
convention='start',
origin='start_day',
offset=None,
dropna=True
)
key (str
, 默认为 None
):
指定用于分组的列名称。如果指定了 key
,Grouper
将按照该列进行分组。
level (int
或 str
, 默认为 None
):
指定用于分组的索引级别的名称或位置。在多级索引的情况下,选择某个级别进行分组。
freq (str
或 DateOffset
, 默认为 None
):
指定时间序列分组的频率,如 'D'
(天)、'W'
(周)、'M'
(月)等。此参数仅在 key
或 level
是日期时间对象时有效。
axis (int
或 str
, 默认为 0
):
指定进行分组的轴。0
表示按行分组,1
表示按列分组。
sort (bool
, 默认为 False
):
是否对结果标签进行排序。如果为 True
,则对分组结果进行排序;否则不排序。
closed ('left'
或 'right'
, 默认为 None
):
在时间序列分组时,指定区间是左闭还是右闭。如果未指定 freq
参数,此参数无效。
label ('left'
或 'right'
, 默认为 None
):
指定区间的标记方式,'right'
表示右边界,'left'
表示左边界。仅在 freq
参数指定时有效。
convention ('start'
, 'end'
, 'e'
, 's'
, 默认为 'start'
):
如果 grouper
是 PeriodIndex
并且指定了 freq
参数,指定分组周期的开始或结束。
origin (Timestamp
或 str
, 默认为 'start_day'
):
调整分组的起点时间戳。可选值包括:
'epoch'
:从 1970-01-01 开始'start'
:时间序列的第一个值'start_day'
:时间序列的第一个午夜'end'
:时间序列的最后一个值'end_day'
:时间序列的最后一天的午夜offset (Timedelta
或 str
, 默认为 None
):
添加到原点的时间偏移量。
dropna (bool
, 默认为 True
):
是否丢弃包含 NA 值的组。如果为 True
,包含 NA 的组将被丢弃;如果为 False
,NA 值将作为组键处理。
pandas.Grouper
Grouper
对象,可以用来进行分组操作,配合 groupby()
函数使用。Grouper
主要用于时间序列数据或多级索引数据的分组操作。它使得按照特定频率、时间点或索引级别对数据进行分组变得更加灵活和方便。
# df.groupby('team')
df.groupby(pd.Grouper('team')).sum()
# 如果是时间,可以60秒一分组
df.groupby(Grouper(key='date', freq='60s'))
# 轴方向
df.groupby(Grouper(level='date', freq='60s', axis=1))
# 按索引
df.groupby(pd.Grouper(level=1)).sum()
单个列:
df.groupby(pd.Grouper('team'))
多个列:
df.groupby([pd.Grouper(freq='1M', key='Date'), 'Buyer']).sum()
df.groupby([pd.Grouper('dt', freq='D'),
pd.Grouper('other_column')
])
df.groupby([pd.Grouper(level='second'), 'A']).sum()
df.groupby([pd.Grouper(level=1), 'A']).sum()
按时间周期分组,需要使用时间字段,如果不是日期时间类型需要进行类型转换:
df['column_name'] = pd.to_datetime(df['column_name'])
df.groupby(pd.Grouper(key='column_name', freq="M")).mean()
可以自定义时间周期:
# 10 年一个周期
df.groupby(pd.cut(df.date,
pd.date_range('1970', '2020', freq='10YS'),
right=False)
).mean()
df.groupby(pd.Grouper(key="Animal"))
相当于 df.groupby('Animal')
。
df = pd.DataFrame(
{
"Animal": ["Falcon", "Parrot", "Falcon", "Falcon", "Parrot"],
"Speed": [100, 5, 200, 300, 15],
}
)
df
'''
Animal Speed
0 Falcon 100
1 Parrot 5
2 Falcon 200
3 Falcon 300
4 Parrot 15
'''
df.groupby(pd.Grouper(key="Animal")).mean()
'''
Speed
Animal
Falcon 200.0
Parrot 10.0
'''
在“发布日期”列上指定重新采样操作:
df = pd.DataFrame(
{
"Publish date": [
pd.Timestamp("2000-01-02"),
pd.Timestamp("2000-01-02"),
pd.Timestamp("2000-01-09"),
pd.Timestamp("2000-01-16")
],
"ID": [0, 1, 2, 3],
"Price": [10, 20, 30, 40]
}
)
df
'''
Publish date ID Price
0 2000-01-02 0 10
1 2000-01-02 1 20
2 2000-01-09 2 30
3 2000-01-16 3 40
'''
df.groupby(pd.Grouper(key="Publish date", freq="1W")).mean()
'''
ID Price
Publish date
2000-01-02 0.5 15.0
2000-01-09 2.0 30.0
2000-01-16 3.0 40.0
'''
如果你想根据固定的时间戳调整箱子的开始:
start, end = '2000-10-01 23:30:00', '2000-10-02 00:30:00'
rng = pd.date_range(start, end, freq='7min')
ts = pd.Series(np.arange(len(rng)) * 3, index=rng)
ts
'''
2000-10-01 23:30:00 0
2000-10-01 23:37:00 3
2000-10-01 23:44:00 6
2000-10-01 23:51:00 9
2000-10-01 23:58:00 12
2000-10-02 00:05:00 15
2000-10-02 00:12:00 18
2000-10-02 00:19:00 21
2000-10-02 00:26:00 24
Freq: 7min, dtype: int64
'''
ts.groupby(pd.Grouper(freq='17min')).sum()
'''
2000-10-01 23:14:00 0
2000-10-01 23:31:00 9
2000-10-01 23:48:00 21
2000-10-02 00:05:00 54
2000-10-02 00:22:00 24
Freq: 17min, dtype: int64
'''
ts.groupby(pd.Grouper(freq='17min', origin='epoch')).sum()
'''
2000-10-01 23:18:00 0
2000-10-01 23:35:00 18
2000-10-01 23:52:00 27
2000-10-02 00:09:00 39
2000-10-02 00:26:00 24
Freq: 17min, dtype: int64
'''
ts.groupby(pd.Grouper(freq='17min', origin='2000-01-01')).sum()
'''
2000-10-01 23:24:00 3
2000-10-01 23:41:00 15
2000-10-01 23:58:00 45
2000-10-02 00:15:00 45
Freq: 17min, dtype: int64
'''
如果要使用偏移Timedelta调整仓位的开始位置,以下两行是等效的:
ts.groupby(pd.Grouper(freq='17min', origin='start')).sum()
'''
2000-10-01 23:30:00 9
2000-10-01 23:47:00 21
2000-10-02 00:04:00 54
2000-10-02 00:21:00 24
Freq: 17min, dtype: int64
'''
ts.groupby(pd.Grouper(freq='17min', offset='23h30min')).sum()
'''
2000-10-01 23:30:00 9
2000-10-01 23:47:00 21
2000-10-02 00:04:00 54
2000-10-02 00:21:00 24
Freq: 17min, dtype: int64
'''
要替换已弃用的base参数的使用,您现在可以使用offset,在本例中,它相当于base=2:
ts.groupby(pd.Grouper(freq='17min', offset='2min')).sum()
'''
2000-10-01 23:16:00 0
2000-10-01 23:33:00 9
2000-10-01 23:50:00 36
2000-10-02 00:07:00 39
2000-10-02 00:24:00 24
Freq: 17min, dtype: int64
'''
假设有一个时间序列数据,我们希望按月份分组计算总和。
import pandas as pd
# 构造示例数据
data = {
'Date': pd.date_range('2023-01-01', periods=100, freq='D'),
'Value': range(100)
}
df = pd.DataFrame(data)
df.set_index('Date', inplace=True)
# 使用 Grouper 按月分组
grouped = df.groupby(pd.Grouper(freq='M')).sum()
# 输出构造的数据和分组结果
print(df)
print(grouped)
输出:
Value
Date
2023-01-01 0
2023-01-02 1
... ...
2023-04-10 99
Value
Date
2023-01-31 465
2023-02-28 1150
2023-03-31 1830
2023-04-30 2350
在这个例子中,我们使用 Grouper(freq='M')
将数据按月份分组,并计算每个月的总和。
import pandas as pd
# 构造示例数据
data = {
'Date': pd.date_range('2022-01-01', periods=365, freq='D'),
'Value': range(365)
}
df = pd.DataFrame(data)
df.set_index('Date', inplace=True)
# 使用 Grouper 按年分组,并指定起始时间为 'start'
grouped = df.groupby(pd.Grouper(freq='Y', origin='start')).sum()
# 输出构造的数据和分组结果
print(df)
print(grouped)
输出:
Value
Date
2022-01-01 0
2022-01-02 1
... ...
2022-12-31 364
Value
Date
2022-12-31 66795
在这个例子中,我们使用 Grouper(freq='Y', origin='start')
将数据按年分组,并计算每年的总和,起始时间为年份的开始。
更新时间:2024-08-11 11:23:25 标签:pandas python 分组