我有一个由子句创建的熊猫数据框:
df = pd.DataFrame({'A':[29,31,48,51,66,64,68], 'B':[1.2,1.7,1.1,0.9,1.3,1.2,1.5]})
看起来像这样:
A B
0 29 1.2
1 31 1.7
2 48 1.1
3 51 0.9
4 66 1.3
5 64 1.2
6 68 1.5
我想对'A'进行分组,而不是精确的值,但abs小于5。所以我想要的是这样的:
A B GroupId
0 29 1.2 1
1 31 1.7 1
2 48 1.1 2
3 51 0.9 2
4 66 1.3 3
5 64 1.2 3
6 68 1.5 3
我该怎么办?
我发现group by a dataframe by values that are just less than a second off - pandas是有帮助的,因此我可以使用:
df['sum'] = [df.loc[(df['A'] - t).abs() < 5, 'B'].sum() for t in df['A']]
变得流畅
A B sum
0 29 1.2 2.9
1 31 1.7 2.9
2 48 1.1 2.0
3 51 0.9 2.0
4 66 1.3 4.0
5 64 1.2 4.0
6 68 1.5 4.0
然后我可以使用'sum'作为ID将这个数据帧分成不同的组。 有什么更好的方法吗?
答案 0 :(得分:1)
由于对列A
的值进行了排序,因此得到的差额为Series.diff
,比较了更大的Series.gt
并通过Series.cumsum
添加了累加总和:
#if necessary
df = df.sort_values('A')
df['GroupId'] = df.A.diff().gt(5).cumsum() + 1
print (df)
A B GroupId
0 29 1.2 1
1 31 1.7 1
2 48 1.1 2
3 51 0.9 2
4 66 1.3 3
5 64 1.2 3
6 68 1.5 3
如果可能,请使用一些负值,并且必须使用绝对值进行处理:
df = pd.DataFrame({'A':[-29,31,-48,51,66,64,68], 'B':[1.2,1.7,1.1,0.9,1.3,1.2,1.5]})
df = df.assign(A1= df.A.abs()).sort_values('A1')
df['GroupId'] = df.A1.diff().gt(5).cumsum() + 1
print (df)
A B A1 GroupId
0 -29 1.2 29 1
1 31 1.7 31 1
2 -48 1.1 48 2
3 51 0.9 51 2
5 64 1.2 64 3
4 66 1.3 66 3
6 68 1.5 68 3