假设我们有以下数据集:
Name Num
First 1
Second 50
Third 110
Fourth 2
Fifth 58
Sixth 105
Seventh 8
我想基于 num 列的每一行之间的最大间隔(例如10)对数据帧进行分组。因此,例如,我希望拥有:
Name Num
First,Fourth,Seventh 1,2,8
Second,Fifth 50,58
Sixth,Third 105,110
我尝试使用Raymond Hettinger's Answer,但是我需要对数据框进行分组,而不仅是对列进行分组,因为我想在之后进行绘制。 我尝试过这个(我首先根据列对数据框进行了排序):
for idx,val in enumerate(df_sorted['num'], start=1):
if idx == 1:
groups =[df_sorted.iloc[idx]]
elif abs(data['pos'][idx] - data['pos'][idx-1]) <= 10:
groups[-1].append(data.iloc[idx,:])
else:
groups.append(data.iloc[idx,:])
但是我在理解列表如何在Python中工作时遇到了一些问题(我一直在R中使用它们)。 不知道是否有使用 groupby 或其他方法(例如 Grouper 用于时间序列)的简便方法。
编辑: 最后,我使用Raymond Hettinger的答案选择以下方法来解决问题:
def cluster(data, maxgap, column):
'''Arrange data into groups where successive elements
differ by no more than *maxgap*
'''
#data.sort() #sort data if necessary
groups = list()
groups = [[data.iloc[0,:]]]
for idx,val in enumerate(data[column]):
if idx > 0:
if abs(val - data[column][idx-1]) <= maxgap:
groups[-1].append(data.iloc[idx,:])
else:
groups.append([data.iloc[idx,:]])
return groups
答案 0 :(得分:1)
我们对数字进行装箱以计算分布,然后根据该分布对其进行分组和列出; N = 24是为您的预期结果量身定制的。对于实际操作,可能很难设置阈值。例如,对于每10个类别,50和58将是一个不同的组。
import pandas as pd
import numpy as np
import io
data = '''
Name Num
First 1
Second 50
Third 110
Fourth 2
Fifth 58
Sixth 105
Seventh 8
'''
df = pd.read_csv(io.StringIO(data), sep='\s+')
df.sort_values('Num', ascending=True, inplace=True, ignore_index=True)
N = 24
category = pd.cut(df['Num'], bins=np.arange(df['Num'].min(), df['Num'].max()+ N, N), right=False)
category.value_counts()
[1, 25) 3
[97, 121) 2
[49, 73) 2
[73, 97) 0
[25, 49) 0
Name: Num, dtype: int64
df.groupby(category).agg(list)
Name Num
Num
[1, 25) [First, Fourth, Seventh] [1, 2, 8]
[25, 49) [] []
[49, 73) [Second, Fifth] [50, 58]
[73, 97) [] []
[97, 121) [Sixth, Third] [105, 110]