【发布时间】:2019-09-29 15:15:29
【问题描述】:
请看下面我的例子,我怎样才能从 groupby 中返回原始 MultiIndex 的所有 3 个级别的数据?
在此示例中:我想按品牌查看总数。我现在使用 map 应用了一种解决方法(见下文,这显示了我希望直接从 groupby 获得的输出)。
brands = ['Tesla','Tesla','Tesla','Peugeot', 'Peugeot', 'Citroen', 'Opel', 'Opel', 'Peugeot', 'Citroen', 'Opel']
years = [2018, 2017,2016, 2018, 2017, 2017, 2018, 2017,2016, 2016,2016]
owners = ['Tesla','Tesla','Tesla','PSA', 'PSA', 'PSA', 'PSA', 'PSA','PSA', 'PSA', 'PSA']
index = pd.MultiIndex.from_arrays([owners, years, brands], names=['owner', 'year', 'brand'])
data = np.random.randint(low=100, high=1000, size=len(index), dtype=int)
weight = np.random.randint(low=1, high=10, size=len(index), dtype=int)
df = pd.DataFrame({'data': data, 'weight': weight},index=index)
df.loc[('PSA', 2017, 'Opel'), 'data'] = np.nan
df.loc[('PSA', 2016, 'Opel'), 'data'] = np.nan
df.loc[('PSA', 2016, 'Citroen'), 'data'] = np.nan
df.loc[('Tesla', 2016, 'Tesla'), 'data'] = np.nan
出来:
data weight
owner year brand
PSA 2016 Citroen NaN 5
Opel NaN 5
Peugeot 250.0 2
2017 Citroen 469.0 4
Opel NaN 5
Peugeot 768.0 5
2018 Opel 237.0 6
Peugeot 663.0 4
Tesla 2016 Tesla NaN 3
2017 Tesla 695.0 6
2018 Tesla 371.0 5
我尝试过使用索引和“级别”以及列和“按”。 我尝试过使用“as_index = False”.sum() 以及“group_keys()”= False 和 .apply(sum)。但我无法在 groupby 输出中恢复品牌列:
grouped = df.groupby(level=['owner', 'year'], group_keys=False) #type: <class 'pandas.core.groupby.generic.DataFrameGroupBy'>
grouped.apply(sum)
出来:
data weight group_data
owner year
PSA 2016 250.0 12.0 750.0
2017 1237.0 14.0 3711.0
2018 900.0 10.0 1800.0
Tesla 2016 0.0 3.0 0.0
2017 695.0 6.0 695.0
2018 371.0 5.0 371.0
类似的:
grouped = df.groupby(by=['owner', 'year'], group_keys=False) #type: <class 'pandas.core.groupby.generic.DataFrameGroupBy'>
grouped.apply(sum)
或:
grouped = df.groupby(by=['owner', 'year'], as_index=False, group_keys=False) #type: <class 'pandas.core.groupby.generic.DataFrameGroupBy'>
grouped.sum()
解决方法:
grouped = df.groupby(level=['owner', 'year'], group_keys=False) #type: <class 'pandas.core.groupby.generic.DataFrameGroupBy'>
df_owner_year = grouped.apply(sum)
s_data = df_owner_year['data']
df['group_data'] = df.index.map(s_data)
df
出来:
data weight group_data
owner year brand
PSA 2016 Citroen NaN 5 250.0
Opel NaN 5 250.0
Peugeot 250.0 2 250.0
2017 Citroen 469.0 4 1237.0
Opel NaN 5 1237.0
Peugeot 768.0 5 1237.0
2018 Opel 237.0 6 900.0
Peugeot 663.0 4 900.0
Tesla 2016 Tesla NaN 3 0.0
2017 Tesla 695.0 6 695.0
2018 Tesla 371.0 5 371.0
【问题讨论】:
-
我不确定我是否理解,但是您的解决方法的结果与您在开始时定义的不一样吗?索引的目的不是唯一标识您要查找的记录/字段吗?如果是这样,那么按整个索引分组不会导致任何变化,因为您是按个人分组。
-
@KenHBS 谢谢。我按索引的第 0 级和第 1 级分组,并尝试在保留第 2 级的情况下将组总数返回到 df 中。
标签: python-3.x pandas