Python 当给定每个组的起始位置索引时,Groupby
我有一系列要分组的值,另一系列包含第一个组之后每个组的起始位置索引(第一个组被理解为从位置索引0开始)。该系列值可以具有任意索引。有没有一种方法可以使用它生成groupby聚合?理想情况下,将保留空组。例如:Python 当给定每个组的起始位置索引时,Groupby,python,pandas,group-by,pandas-groupby,Python,Pandas,Group By,Pandas Groupby,我有一系列要分组的值,另一系列包含第一个组之后每个组的起始位置索引(第一个组被理解为从位置索引0开始)。该系列值可以具有任意索引。有没有一种方法可以使用它生成groupby聚合?理想情况下,将保留空组。例如: values = pd.Series(np.arange(10, 20), index=np.arange(110, 120)) group_indices = pd.Series([3, 3, 8]) 现在,values.groupby(group\u index)应该分组,以便第一组
values = pd.Series(np.arange(10, 20), index=np.arange(110, 120))
group_indices = pd.Series([3, 3, 8])
现在,
values.groupby(group\u index)
应该分组,以便第一组是values.iloc[:3]
,第二组是values.iloc[3:3]
(空组),第三组是values.iloc[3:8]
,第四组是values.iloc[8:
,和values.groupby(group\u index.mean()
将是pd.Series([11.0,NaN,15.0,18.5])
让我们稍微更改组标识,以便组名称(1,2,3)可见
group_indices = pd.Series([1,2,3],index=[0, 3, 8])
然后
会给你想要的
请注意,group\u index.reindex(values.index,method='ffill')
为您提供
0 1
1 1
2 1
3 2
4 2
5 2
6 2
7 2
8 3
9 3
它为每行
值
分配一个组号 让我们稍微更改组_指示,以便组名(1,2,3)可见
group_indices = pd.Series([1,2,3],index=[0, 3, 8])
然后
会给你想要的
请注意,group\u index.reindex(values.index,method='ffill')
为您提供
0 1
1 1
2 1
3 2
4 2
5 2
6 2
7 2
8 3
9 3
它为每行值
分配一个组号 直接按常规:
要计算“空”组-只需删除
如果s.size
检查:
In [1304]: group_indices = pd.Series([3, 3, 8])
In [1305]: pd.Series([s.mean() for s in np.split(values, group_indices)])
Out[1305]:
0 11.0
1 NaN
2 15.0
3 18.5
dtype: float64
直截了当地说:
要计算“空”组-只需删除
如果s.size
检查:
In [1304]: group_indices = pd.Series([3, 3, 8])
In [1305]: pd.Series([s.mean() for s in np.split(values, group_indices)])
Out[1305]:
0 11.0
1 NaN
2 15.0
3 18.5
dtype: float64
我的解决方案包括保持输入不变,并进行一些丑陋的调整:
pd.DataFrame(values).assign(group=pd.cut(pd.DataFrame(values).index,
[-1,2,7,np.inf], labels=[0,1,2])).groupby('group').mean()
输出
0
group
0 11.0
1 15.0
2 18.5
我的解决方案包括保持输入不变,并进行一些丑陋的调整:
pd.DataFrame(values).assign(group=pd.cut(pd.DataFrame(values).index,
[-1,2,7,np.inf], labels=[0,1,2])).groupby('group').mean()
输出
0
group
0 11.0
1 15.0
2 18.5
根据您的更新,这里有一种奇怪的方法可以使用
pd.merge\u asof
实现这一点。在处理从0到系列中的第一个索引的第一组时,需要特别小心
import pandas as pd
import numpy as np
(pd.merge_asof(values.to_frame('val'),
values.iloc[np.r_[group_indices]].reset_index().reset_index().drop(columns=0),
left_index=True, right_on='index',
direction='backward')
.fillna({'level_0': -1}) # Because your first group is 0: first index
.groupby('level_0').val.mean()
.reindex([-1]+[*range(len(group_indices))]) # Get 0 size groups in output
)
根据您的更新,这里有一种奇怪的方法可以使用
pd.merge\u asof
实现这一点。在处理从0到系列中的第一个索引的第一组时,需要特别小心
import pandas as pd
import numpy as np
(pd.merge_asof(values.to_frame('val'),
values.iloc[np.r_[group_indices]].reset_index().reset_index().drop(columns=0),
left_index=True, right_on='index',
direction='backward')
.fillna({'level_0': -1}) # Because your first group is 0: first index
.groupby('level_0').val.mean()
.reindex([-1]+[*range(len(group_indices))]) # Get 0 size groups in output
)
这里有一个简单的方法
values.groupby(values.index.isin(group_indices).cumsum()).mean()
Out[454]:
1 11.0
2 15.0
3 18.5
dtype: float64
这里有一个简单的方法
values.groupby(values.index.isin(group_indices).cumsum()).mean()
Out[454]:
1 11.0
2 15.0
3 18.5
dtype: float64
感谢所有的答案,尤其是。以下内容将生成正确的组并跳过空组
# First, add the final index to `group_indices` so that
# we have a series of right endpoints, or interval upper bounds
upper_bounds = group_indices.append(pd.Series(values.shape[0]), ignore_index=True)
# Compute indices of nonempty groups
lower_bounds = upper_bounds.shift(fill_value=0)
nonempty_group_idxs = upper_bounds != lower_bounds
# Get means indexed from 0 to n_nonempty_groups-1
means = values.groupby(pd.RangeIndex(values.shape[0]).isin(upper_bounds).cumsum()).mean()
# Reassign index for the correct groups
means.index = nonempty_group_idxs.index[nonempty_group_idxs]
这将有一个非连续索引,跳过的元素对应于原始groupby
中的空组。如果您想在这些点中放置NaN
,您可以这样做
means = means.reindex(index=pd.RangeIndex(group_indices.shape[0]))
感谢所有的答案,尤其是。以下内容将生成正确的组并跳过空组
# First, add the final index to `group_indices` so that
# we have a series of right endpoints, or interval upper bounds
upper_bounds = group_indices.append(pd.Series(values.shape[0]), ignore_index=True)
# Compute indices of nonempty groups
lower_bounds = upper_bounds.shift(fill_value=0)
nonempty_group_idxs = upper_bounds != lower_bounds
# Get means indexed from 0 to n_nonempty_groups-1
means = values.groupby(pd.RangeIndex(values.shape[0]).isin(upper_bounds).cumsum()).mean()
# Reassign index for the correct groups
means.index = nonempty_group_idxs.index[nonempty_group_idxs]
这将有一个非连续索引,跳过的元素对应于原始groupby
中的空组。如果您想在这些点中放置NaN
,您可以这样做
means = means.reindex(index=pd.RangeIndex(group_indices.shape[0]))
将系列转换为数据框架对你有用吗?@Yuca确定,只要它得到了工作就可以了?将系列转换为数据框架对你有用吗?@Yuca确定,只要它得到了工作就可以了我喜欢使用ffill:-)我喜欢使用ffill:-)这样可以保持空组吗?请参阅对我的问题的编辑。@BallpointBenB no cumsum将不会创建空组,您需要使用pd.cut
values.groupby(pd.cut(values.index,pd.Series([0,3,3,8])。drop_duplicates())进行检查。mean()
这样可以保留空组吗?请参阅对我的问题的编辑。@BallpointBenB no cumsum不会创建空组,您需要检查pd.cutvalues.groupby(pd.cut(values.index,pd.Series([0,3,3,8])。drop_duplicates())。mean()
@BallpointBen以说明“空”组-如果s.sizecheck@BallpointBen说明“空”组-如果s.size检查,只需跳过