使用 pivot-table 计算百分比和绘图
Calculation percentage and plot using pivot-table
我需要在 pandas 中绘制带有枢轴 table 的百分比图形,您有什么想法吗?我如何计算百分比?感谢您的指导!
这是我的代码:
df.pivot_table(index='obito', values=['asma', 'cardiopatia','diabetes','doenca_renal','obesidade']).T.plot(kind ='bar' , stacked = True)
我拥有的这部分数据框:
{'nome_munic': {66: 'Ferraz de Vasconcelos',
97: 'São Paulo',
100: 'São José dos Campos',
207: 'Mauá',
249: 'Cajamar',
258: 'Votuporanga',
285: 'Ferraz de Vasconcelos',
290: 'São Paulo',
345: 'São Pedro',
378: 'São Paulo'},
'codigo_ibge': {66: 3515707,
97: 3550308,
100: 3549904,
207: 3529401,
249: 3509205,
258: 3557105,
285: 3515707,
290: 3550308,
345: 3550407,
378: 3550308},
'idade': {66: 86,
97: 62,
100: 58,
207: 54,
249: 62,
258: 37,
285: 54,
290: 71,
345: 79,
378: 61},
'sexo': {66: 0,
97: 0,
100: 0,
207: 1,
249: 0,
258: 1,
285: 0,
290: 0,
345: 0,
378: 0},
'obito': {66: 1,
97: 0,
100: 0,
207: 1,
249: 1,
258: 1,
285: 0,
290: 1,
345: 1,
378: 0},
'asma': {66: 0,
97: 0,
100: 0,
207: 1,
249: 0,
258: 0,
285: 0,
290: 0,
345: 0,
378: 0},
'cardiopatia': {66: 1,
97: 0,
100: 1,
207: 1,
249: 1,
258: 0,
285: 1,
290: 1,
345: 0,
378: 0},
'diabetes': {66: 1,
97: 1,
100: 0,
207: 0,
249: 1,
258: 1,
285: 0,
290: 0,
345: 1,
378: 0},
'doenca_hematologica': {66: 0,
97: 0,
100: 0,
207: 0,
249: 0,
258: 0,
285: 0,
290: 0,
345: 0,
378: 0},
'doenca_hepatica': {66: 0,
97: 0,
100: 0,
207: 0,
249: 0,
258: 0,
285: 0,
290: 0,
345: 0,
378: 0},
'doenca_neurologica': {66: 0,
97: 0,
100: 0,
207: 0,
249: 0,
258: 0,
285: 0,
290: 1,
345: 0,
378: 0},
'doenca_renal': {66: 0,
97: 0,
100: 0,
207: 0,
249: 0,
258: 0,
285: 0,
290: 0,
345: 0,
378: 0},
'imunodepressao': {66: 0,
97: 0,
100: 1,
207: 0,
249: 0,
258: 0,
285: 0,
290: 0,
345: 0,
378: 0},
'obesidade': {66: 0,
97: 0,
100: 0,
207: 0,
249: 1,
258: 1,
285: 0,
290: 0,
345: 0,
378: 0},
'outros_fatores_de_risco': {66: 0,
97: 0,
100: 1,
207: 0,
249: 0,
258: 0,
285: 0,
290: 0,
345: 0,
378: 1},
'pneumopatia': {66: 0,
97: 1,
100: 0,
207: 0,
249: 0,
258: 0,
285: 0,
290: 0,
345: 0,
378: 0},
'puerpera': {66: 0,
97: 0,
100: 0,
207: 0,
249: 0,
258: 0,
285: 0,
290: 0,
345: 0,
378: 0},
'sindrome_de_down': {66: 0,
97: 0,
100: 0,
207: 0,
249: 0,
258: 0,
285: 0,
290: 0,
345: 0,
378: 0}}
感谢您的支持。
默认的 aggfunc 是 np.mean
但是它不计算每列的平均值或类似的东西,它计算单元格的平均值。简而言之,对于每种情况,它都是 1
的数量除以 1
的数量 + 0
的数量。这有时是有道理的,但对您的数据而言并非如此。
>>> df[['asma', 'cardiopatia','diabetes','doenca_renal','obesidade', 'obito']]
asma cardiopatia diabetes doenca_renal obesidade obito
66 0 1 1 0 0 1
97 0 0 1 0 0 0
100 0 1 0 0 0 0
207 1 1 0 0 0 1
249 0 1 1 0 1 1
258 0 0 1 0 1 1
285 0 1 0 0 0 0
290 0 1 0 0 0 1
345 0 0 1 0 0 1
378 0 0 0 0 0 0
>>> df.pivot_table(index='obito', values=['asma', 'cardiopatia','diabetes','doenca_renal','obesidade'])
asma cardiopatia diabetes doenca_renal obesidade
obito
0 0.000000 0.500000 0.250000 0 0.000000
1 0.166667 0.666667 0.666667 0 0.333333
相反,您可能想计算每个单元格的患者总数,然后除以列总数:
>>> counts = df.pivot_table(index='obito', values=['asma', 'cardiopatia','diabetes','doenca_renal','obesidade'], aggfunc=np.sum)
>>> counts / counts.sum()
asma cardiopatia diabetes doenca_renal obesidade
obito
0 0.0 0.333333 0.2 NaN 0.0
1 1.0 0.666667 0.8 NaN 1.0
请注意现在每列的总和为 1。doenca_renal
是 NaN
,因为样本中根本没有患者,因此未定义百分比。如果您只想绘制具有 obito=1
的百分比,那么您可以这样做:
>>> from matplotlib import ticker
>>> ax = (counts / counts.sum()).loc[1].plot.bar(rot=0)
>>> ax.yaxis.set_major_formatter(ticker.PercentFormatter(xmax=1))
如果要在栏上注释百分比,请参阅 this other question
我需要在 pandas 中绘制带有枢轴 table 的百分比图形,您有什么想法吗?我如何计算百分比?感谢您的指导!
这是我的代码:
df.pivot_table(index='obito', values=['asma', 'cardiopatia','diabetes','doenca_renal','obesidade']).T.plot(kind ='bar' , stacked = True)
我拥有的这部分数据框:
{'nome_munic': {66: 'Ferraz de Vasconcelos',
97: 'São Paulo',
100: 'São José dos Campos',
207: 'Mauá',
249: 'Cajamar',
258: 'Votuporanga',
285: 'Ferraz de Vasconcelos',
290: 'São Paulo',
345: 'São Pedro',
378: 'São Paulo'},
'codigo_ibge': {66: 3515707,
97: 3550308,
100: 3549904,
207: 3529401,
249: 3509205,
258: 3557105,
285: 3515707,
290: 3550308,
345: 3550407,
378: 3550308},
'idade': {66: 86,
97: 62,
100: 58,
207: 54,
249: 62,
258: 37,
285: 54,
290: 71,
345: 79,
378: 61},
'sexo': {66: 0,
97: 0,
100: 0,
207: 1,
249: 0,
258: 1,
285: 0,
290: 0,
345: 0,
378: 0},
'obito': {66: 1,
97: 0,
100: 0,
207: 1,
249: 1,
258: 1,
285: 0,
290: 1,
345: 1,
378: 0},
'asma': {66: 0,
97: 0,
100: 0,
207: 1,
249: 0,
258: 0,
285: 0,
290: 0,
345: 0,
378: 0},
'cardiopatia': {66: 1,
97: 0,
100: 1,
207: 1,
249: 1,
258: 0,
285: 1,
290: 1,
345: 0,
378: 0},
'diabetes': {66: 1,
97: 1,
100: 0,
207: 0,
249: 1,
258: 1,
285: 0,
290: 0,
345: 1,
378: 0},
'doenca_hematologica': {66: 0,
97: 0,
100: 0,
207: 0,
249: 0,
258: 0,
285: 0,
290: 0,
345: 0,
378: 0},
'doenca_hepatica': {66: 0,
97: 0,
100: 0,
207: 0,
249: 0,
258: 0,
285: 0,
290: 0,
345: 0,
378: 0},
'doenca_neurologica': {66: 0,
97: 0,
100: 0,
207: 0,
249: 0,
258: 0,
285: 0,
290: 1,
345: 0,
378: 0},
'doenca_renal': {66: 0,
97: 0,
100: 0,
207: 0,
249: 0,
258: 0,
285: 0,
290: 0,
345: 0,
378: 0},
'imunodepressao': {66: 0,
97: 0,
100: 1,
207: 0,
249: 0,
258: 0,
285: 0,
290: 0,
345: 0,
378: 0},
'obesidade': {66: 0,
97: 0,
100: 0,
207: 0,
249: 1,
258: 1,
285: 0,
290: 0,
345: 0,
378: 0},
'outros_fatores_de_risco': {66: 0,
97: 0,
100: 1,
207: 0,
249: 0,
258: 0,
285: 0,
290: 0,
345: 0,
378: 1},
'pneumopatia': {66: 0,
97: 1,
100: 0,
207: 0,
249: 0,
258: 0,
285: 0,
290: 0,
345: 0,
378: 0},
'puerpera': {66: 0,
97: 0,
100: 0,
207: 0,
249: 0,
258: 0,
285: 0,
290: 0,
345: 0,
378: 0},
'sindrome_de_down': {66: 0,
97: 0,
100: 0,
207: 0,
249: 0,
258: 0,
285: 0,
290: 0,
345: 0,
378: 0}}
感谢您的支持。
默认的 aggfunc 是 np.mean
但是它不计算每列的平均值或类似的东西,它计算单元格的平均值。简而言之,对于每种情况,它都是 1
的数量除以 1
的数量 + 0
的数量。这有时是有道理的,但对您的数据而言并非如此。
>>> df[['asma', 'cardiopatia','diabetes','doenca_renal','obesidade', 'obito']]
asma cardiopatia diabetes doenca_renal obesidade obito
66 0 1 1 0 0 1
97 0 0 1 0 0 0
100 0 1 0 0 0 0
207 1 1 0 0 0 1
249 0 1 1 0 1 1
258 0 0 1 0 1 1
285 0 1 0 0 0 0
290 0 1 0 0 0 1
345 0 0 1 0 0 1
378 0 0 0 0 0 0
>>> df.pivot_table(index='obito', values=['asma', 'cardiopatia','diabetes','doenca_renal','obesidade'])
asma cardiopatia diabetes doenca_renal obesidade
obito
0 0.000000 0.500000 0.250000 0 0.000000
1 0.166667 0.666667 0.666667 0 0.333333
相反,您可能想计算每个单元格的患者总数,然后除以列总数:
>>> counts = df.pivot_table(index='obito', values=['asma', 'cardiopatia','diabetes','doenca_renal','obesidade'], aggfunc=np.sum)
>>> counts / counts.sum()
asma cardiopatia diabetes doenca_renal obesidade
obito
0 0.0 0.333333 0.2 NaN 0.0
1 1.0 0.666667 0.8 NaN 1.0
请注意现在每列的总和为 1。doenca_renal
是 NaN
,因为样本中根本没有患者,因此未定义百分比。如果您只想绘制具有 obito=1
的百分比,那么您可以这样做:
>>> from matplotlib import ticker
>>> ax = (counts / counts.sum()).loc[1].plot.bar(rot=0)
>>> ax.yaxis.set_major_formatter(ticker.PercentFormatter(xmax=1))
如果要在栏上注释百分比,请参阅 this other question