首页 > 解决方案 > 在数据框上使用自定义条件的 Pandas 数据透视表

问题描述

我想根据数据框中的自定义条件制作一个数据透视表:

数据框如下所示:

>>> df = pd.DataFrame({"Area": ["A", "A", "B", "A", "C", "A", "D", "A"],
                       "City" : ["X", "Y", "Z", "P", "Q", "R", "S", "X"],
                       "Condition" : ["Good", "Bad", "Good", "Good", "Good", "Bad", "Good", "Good"], 
                       "Population" : [100,150,50,200,170,390,80,100]
                       "Pincode" : ["X1", "Y1", "Z1", "P1", "Q1", "R1", "S1", "X2"] })
>>> df
  Area City Condition   Population Pincode
 0    A    X      Good   100       X1
 1    A    Y       Bad   150       Y1
 2    B    Z      Good   50        Z1
 3    A    P      Good   200       P1
 4    C    Q      Good   170       Q1
 5    A    R       Bad   390       R1
 6    D    S      Good   80        S1
 7    A    X      Good   100       X2

现在我想以df某种方式旋转数据框,以便我可以看到每个区域的唯一城市数量以及相应的“好”城市数量以及该地区的人口。

我期望这样的输出:

Area  city_count  good_city_count   Population
A        4        2                 940
B        1        1                 50
C        1        1                 170
D        1        1                 80
All      7        5                 1240

我可以给aggfunc参数一个字典,但这并没有给我在好城市之间划分的城市计数。

>>> city_count = df.pivot_table(index=["Area"],
                                values=["City", "Population"],
                                aggfunc={"City": lambda x: len(x.unique()),
                                         "Population": "sum"},
                                margins=True)

    Area    City    Population
0   A       4       940
1   B       1       50
2   C       1       170
3   D       1       80
4   All     7       1240

我可以合并两个不同的数据透视表——一个带有城市数量,另一个带有人口,但这对于带有大aggfunc字典的大型数据集是不可扩展的。

标签: pythonpandaspivot-table

解决方案


添加新参数columnsfill_value也可以nunique用于聚合函数:

city_count = df.pivot_table(index = "Area", 
                            values = "City", 
                            columns='Condition', 
                            aggfunc = lambda x : x.nunique(), 
                            margins = True,
                            fill_value=0)
print (city_count)
Condition  Bad  Good  All
Area                     
A            2     2    4
B            0     1    1
C            0     1    1
D            0     1    1
All          2     5    7

最后如果需要将索引转换为列并更改列名:

city_count = city_count.add_suffix('_count').reset_index().rename_axis(None, 1)
print (city_count)
  Area  Bad_count  Good_count  All_count
0    A          2           2          4
1    B          0           1          1
2    C          0           1          1
3    D          0           1          1
4  All          2           5          7

编辑:

d = {'City':'nunique','Population':'sum', 'good_city_count':'nunique'}
d1 = {'City':'city_count','Condition':'good_city_count'}

mask = df["Condition"] == 'Good'
df = (df.assign(good_city_count = lambda x: np.where(mask, x['City'], np.nan))
       .groupby('Area')
       .agg(d)
       .rename(columns=d1))

df = df.append(df.sum().rename('All')).reset_index()

print (df)
  Area  city_count  Population  good_city_count
0    A           4         940                2
1    B           1          50                1
2    C           1         170                1
3    D           1          80                1
4  All           7        1240                5

推荐阅读