python - 如何在没有多级索引的情况下创建 groupby 数据框
问题描述
我有以下 pandasgroupby
对象,我想将结果转换为新的数据框。
以下是获取条件概率的代码:
bin_probs = data.groupby('season')['bin'].value_counts()/data.groupby('season')['bin'].count()
我已经尝试了以下代码,但它返回如下。
- 我喜欢
season
填写每一行。我怎样才能做到这一点?
a = pd.DataFrame(data_5.groupby('season')['bin'].value_counts()/data_5.groupby('season')['bin'].count())
解决方案
a
是一个 DataFrame,但有一个 2 级索引,所以我的解释是你想要一个没有多级索引的数据框。- 当索引中的名称和列相同时,索引不能被重置。
- 使用
pandas.Series.reset_index
和 setname='normalized_bin
重命名bin
列。- 这不适用于 OP 中的实现,因为那是一个数据框。
- 这适用于以下实现,因为 a
pandas.Series
是用.groupby
.
- 对列进行规范化的正确方法是
normalize=True
使用.value_counts
.
import pandas as pd
import random # for test data
import numpy as np # for test data
# setup a dataframe with test data
np.random.seed(365)
random.seed(365)
rows = 1100
data = {'bin': np.random.randint(10, size=(rows)),
'season': [random.choice(['fall', 'winter', 'summer', 'spring']) for _ in range(rows)]}
df = pd.DataFrame(data)
# display(df.head())
bin season
0 2 summer
1 4 winter
2 1 summer
3 5 winter
4 2 spring
# groupby, normalize and reset the the Series index
a = df.groupby(['season'])['bin'].value_counts(normalize=True).reset_index(name='normalized_bin')
# display(a.head(15))
season bin normalized_bin
0 fall 2 0.15600
1 fall 9 0.11600
2 fall 3 0.10800
3 fall 4 0.10400
4 fall 6 0.10000
5 fall 0 0.09600
6 fall 8 0.09600
7 fall 5 0.08400
8 fall 7 0.08000
9 fall 1 0.06000
10 spring 0 0.11524
11 spring 8 0.11524
12 spring 9 0.11524
13 spring 3 0.11152
14 spring 1 0.10037
使用 OP 代码a
- 如上所述,用于
normalize=True
获取标准化值 - OP 中的解决方案创建了一个 DataFrame,因为它
.groupby
是用 DataFrame 构造函数包装的pandas.DataFrame
。- 要重置索引,您必须首先使用
pandas.DataFrame.rename
该bin
列,然后使用pandas.DataFrame.reset_index
- 要重置索引,您必须首先使用
a = pd.DataFrame(df.groupby('season')['bin'].value_counts()/df.groupby('season')['bin'].count()).rename(columns={'bin': 'normalized_bin'}).reset_index()
其他资源
- 请参阅Pandas 无法重置索引,因为存在名称以通过
level
.
绘图
- 通过使用 ,从多索引系列中绘制更容易
pandas.Series.unstack()
,然后使用pandas.DataFrame.plot.bar
- 对于并排栏,设置
stacked=False
. - 条形均等于 1,因为这是标准化数据。
s = df.groupby(['season'])['bin'].value_counts(normalize=True).unstack()
# plot a stacked bar
s.plot.bar(stacked=True, figsize=(8, 6))
plt.legend(title='bin', bbox_to_anchor=(1.05, 1), loc='upper left')
推荐阅读
- flexbox - 如何使用 flexbox 获得真正的中心?
- aframe - 如何从透明材质投射阴影?
- android - 渲染 Android Studio 4.3
- java - Android Spinner 重新选择项目
- r - 如何使用 guide_coloursteps 仅标记某些级别?
- github - 如何创建覆盖不同目录中多个文件的拉取请求?
- excel - 使用来自数据验证的数据将 Excel 工作表导出为 PDF
- javascript - TypeError:无法读取未定义行的属性“地图”(Row.js:18)React JS
- python - plotly - 在 Plot.JS 中使用 graph_objects.Figure 轨迹
- sql - 如果表中没有可能的主键怎么办?