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

时间:2018-09-05 12:06:00

标签: python pandas pandas-groupby

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

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

我想将area1和area2的计数(10 + 20)加到区域4(30)中。 area3的数字计数保持不变(5)。通过使用groupby和sum来获得pd.series series1,如下所示。

series1 = frame1.groupby(['FusedIntoArea'])['numbercount'].sum()
series1

问题是我想将此分组依据和求和运算扩展到几年的几个融合区域。在第3帧中显示了该区域的扩展融合数据。 Area1和Area2融合形成Area4(就像以前一样),但是现在还有更多:在那之后的一年,Area4和Area3融合形成Area5,而Area6保持不变。融合数据的格式类似于下面frame2中的格式:

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(在年份中保持不变)的总数number(TotalNumber),如第4帧所示。任何帮助深表感谢。我应该使用联接还是合并操作?预先感谢。

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

1 个答案:

答案 0 :(得分:0)

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

首先创建一个词典,告诉您在哪个区域进行融合:

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'}

完成此操作后,您可以在NewArea上使用replace来创建frame3['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