如何合并两个pandas DataFrames并聚合一个特定列

wan*_*020 4 python pandas

我有2个DataFrames:

         city  count    school
0    New York      1  school_3
1  Washington      1  School_4
2  Washington      1  School_5
3          LA      1  School_1
4          LA      1  School_4

         city  count    school
0    New York      1  School_3
1  Washington      1  School_1
2          LA      1  School_3
3          LA      2  School_4
Run Code Online (Sandbox Code Playgroud)

我想得到这个结果:

         city  count    school
0    New York      2  school_3
1  Washington      1  School_1
2  Washington      1  School_4
3  Washington      1  School_5
4          LA      1  School_1
5          LA      1  School_3
6          LA      3  School_4
Run Code Online (Sandbox Code Playgroud)

以下是代码.

d1 = [{'city':'New York', 'school':'school_3', 'count':1},
      {'city':'Washington', 'school':'School_4', 'count':1},
      {'city':'Washington', 'school':'School_5', 'count':1},
      {'city':'LA', 'school':'School_1', 'count':1},
      {'city':'LA', 'school':'School_4', 'count':1}]


d2 = [{'city':'New York', 'school':'School_3', 'count':1},
      {'city':'Washington', 'school':'School_1', 'count':1},
      {'city':'LA', 'school':'School_3', 'count':1},
      {'city':'LA', 'school':'School_4', 'count':2}]

x1 = pd.DataFrame(d1)
x2 = pd.DataFrame(d2)
#just get empty DataFrame
print pd.merge(x1, x2)
Run Code Online (Sandbox Code Playgroud)

如何获得汇总结果?

ely*_*ase 6

你可以做:

>>> pd.concat([x1, x2]).groupby(["city", "school"], as_index=False)["count"].sum()
       city    school        count
0          LA  School_1      1
1          LA  School_3      1
2          LA  School_4      3
3    New York  School_3      1
4    New York  school_3      1
5  Washington  School_1      1
6  Washington  School_4      1
7  Washington  School_5      1
Run Code Online (Sandbox Code Playgroud)

请注意,纽约出现2次是因为数据中的拼写错误(school_3vs School_3).


aus*_*acy 5

这是与 @elyase 的解决方案略有不同的实现,使用pandas.DataFrame.merge(...)

x1.merge(x2,on=['city', 'school', 'count'], how='outer').groupby(['city', 'school'], as_index=False)['count'].sum()
Run Code Online (Sandbox Code Playgroud)

此方法的计时ipython notebook %timeit速度比 @elyase 的稍快(<1ms)

100 loops, best of 3: 6.25 ms per loop  #using concat(...) with @elyase's solution
100 loops, best of 3: 5.49 ms per loop #using merge(...) in this solution
Run Code Online (Sandbox Code Playgroud)

另外,如果您想使用pandas aggregate功能,您还可以执行以下操作:

x1.merge(x2,on=['city', 'school', 'count'], how='outer').groupby(['city', 'school'], as_index=False).agg(numpy.sum)
Run Code Online (Sandbox Code Playgroud)

唯一的免责声明是,使用agg(...)是 3 种解决方案中最慢的。

显然,这 3 个都提供了正确的结果:

         city    school  count
0          LA  School_1      1
1          LA  School_3      1
2          LA  School_4      3
3    New York  School_3      1
4    New York  school_3      1
5  Washington  School_1      1
6  Washington  School_4      1
7  Washington  School_5      1
Run Code Online (Sandbox Code Playgroud)