在熊猫中用Groupby和sum重复操作



一段时间以来,我一直在尝试解决以下问题。希望有人可以帮助我。我尝试总结不同领域的数字计数(例如出生(。如下表所示,我有一个数据集,其中,例如,区域 1 和 2 在融合区域4中相遇。区域 3 不受影响。

import pandas as pd
data1  = { 
"OldArea" : ['area1','area2','area3'],
"numbercount" : [10,20,5],
"FusedIntoArea" : ['area4','area4','area3']
}
frame1 = pd.DataFrame(data1, columns=['OldArea', 'FusedIntoArea', 'numbercount'])
frame1

我想将区域 1 和区域 2 (10 + 20( 的数字计数相加到区域 4 (30( 中。区域 3 的计数保持不变 (5(。这通过使用 groupby 和 sum 来获取 pd.series series1

,如下所示。
series1 = frame1.groupby(['FusedIntoArea'])['numbercount'].sum()
series1

问题是我想在几年内将这种分组和求和操作扩展到多个区域的融合。这些区域的扩展融合数据如第 3 帧所示。Area1 和 Area2 融合形成 Area4(就像以前一样(,但现在还有更多:在那之后的一年里,Area4 和 Area3 融合形成 Area5,而 Area6 多年来保持不变。融合数据的格式类似于下面的第 2 帧:

data2 = {
'year0' : ['area1', 'area2', 'area3', 'area6'],
'year1' : ['area4', 'area4', 'area3', 'area6'],
'year2' : ['area5', 'area5', 'area5', 'area6']
}
frame2 = pd.DataFrame(data2, columns = ['year0', 'year1', 'year2'])
frame2

数字计数的数据(例如,融合前或从融合的那一刻开始的出生(现在在一个单独的帧中,即 frame3。

data3  = { 
"area" : ['area1', 'area2','area3', 'area4', 'area5', 'area6'],
"numbercount" : [10,20,5,35, 15,25],
}
frame3 = pd.DataFrame(data3, columns=['area', 'numbercount'])
frame3

我试图得到的结果是新形成的区域5(融合后1 + 2 + 3 + 4 + 5(和6(多年来不变(的总数(TotalNumber(,如frame4所示。任何帮助都非常感谢。我应该使用联接还是合并操作?提前谢谢。

data4  = { 
"OldAreas" :[1,2,3,4,5,6],
"NewArea" : ['area5','area5','area5','area5','area5','area6'],
"TotalNumber" : [85,85,85,85,85, 25]
}
frame4 = pd.DataFrame(data4, columns=['NewArea', 'TotalNumber'])
frame4

您可以使用字典来映射现有数据。

首先创建一个字典,告诉你它融合在哪个区域的每个区域:

areas_to_fuse = dict(zip(frame2.year0.values, frame2.year2.values))
areas_to_fuse = {**areas_to_fuse,**dict(zip(frame2.year1.values, frame2.year2.values))}

{'area1': 'area5',
'area2': 'area5',
'area3': 'area5',
'area4': 'area5',
'area6': 'area6'}

完成此操作后,您可以使用replace创建NewAreaframe3['area'](请注意,replace允许保留字典键中不存在的值,如果您更喜欢缺失值,请使用map(

frame3['NewArea'] = frame3.area.replace(areas_to_fuse)

然后,您可以为值对应的每个区域创建第二个字典编码,并将其映射到您的列NewArea

newvalues = frame3.groupby('NewArea').numbercount.sum().to_dict()
frame3['TotalNumber'] = frame3.NewArea.map(newvalues)
frame3[['NewArea','TotalNumber']]
NewArea     TotalNumber
0   area5       85
1   area5       85
2   area5       85
3   area5       85
4   area5       85
5   area6       25

最新更新