用Pandas Groupby模块创建非层次化的列
在这篇文章中,我们将看到在应用groupby模块时,有几种方法可以创建非层次性的列。
我们使用财富500强公司的数据集来展示问题和解决方案。我们必须从data.world网站上抓取一个副本。
对于每个 “部门 “和 “行业”,找到总数、平均雇员和最低、最高收入变化。
让我们看看一个实现例子:
第1步:让我们开始导入pandas和以公司 “Rank “为索引的数据集。
import pandas as pd
# load the dataset
df = pd.read_csv(
"https://raw.githubusercontent.com/sasankac/TestDataSet/master/Fortune500.csv")
# print the columns
print(df.columns)
输出:
第2步:数据集中有许多我们不感兴趣的列,如总部所在地、地址……我将把它们从数据集中删除。
# remove unwanted columns
remove_columns =['Website','Hqaddr','Hqzip', 'Hqtel',
'Ceo','Ceo-title', 'Address', 'Ticker',
'Prftchange', 'Assets', 'Totshequity']
df = df.drop(columns= remove_columns,axis = 1)
print(df.columns)
输出:
方法 1:
在这个方法中,我们将使用to_flat_index方法来输出非层次化的列。让我,首先分组,确定下面的数据的列。对于每个 “部门 “和 “行业”,找到总数,平均雇员,以及最小,最大收入变化。groupby和聚合的语法如下
语法: df.groupby(['grouping column1′,' grouping column2"]).agg({ 'aggregate column1' :['aggregate function1′, 'aggregate function2' })
现在根据要求,让我们把数据集中的列名映射到语法中。
- 分组列–‘部门’、’行业’。
- 汇总列 – ‘雇员’, ‘变化’.
- 聚合函数 – ‘sum’, ‘mean’, ‘min’ “max3. 通过应用上述语法得到的结果。
实现:
df_result = (df
.groupby(['Sector','Industry'])
.agg({'Employees':['sum', 'mean'],
'Revchange':['min','max']}))
# printing top 15 rows
df_result.head(15)
输出:
看一下结果,我们有6个层次化的列,即雇员的总和和平均数(用黄色突出显示)和Revchange的最小、最大列。我们可以使用pandas 0.24版本中引入的.to_flat_index方法,将分层列转换成非分层列。
df_result.columns = ['_'.join(cols).lower()
for cols in df_result.columns.to_flat_index()]
df_result.head(10)
输出:
一旦函数被成功应用,所有的列都不会被扁平化,列名会被附加上聚合函数。
完整实现:
"""
Program: For each "Sector" and "Industry" Find the total, average employees, and the minimum, maximum revenue change.
"""
import pandas as pd
"""
Function: Convert hierarchial columns to non-hierarchial columns
params: dataframe with hierarchial columns
return : dataframe with non-hierarchial columns
"""
def return_non_hierarchial(df):
df.columns = ['_'.join(x) for x in df.columns.to_flat_index()]
return df
# load the dataset with rank as index
df = pd.read_csv(
"https://raw.githubusercontent.com/sasankac/TestDataSet/master/Fortune500.csv", index_col="Rank")
# remove unwanted columns
remove_columns = ['Website', 'Hqaddr', 'Hqzip', 'Hqtel', 'Ceo',
'Ceo-title', 'Address', 'Ticker', 'Prftchange',
'Assets', 'Totshequity']
df = df.drop(columns=remove_columns, axis=1)
# Identify the data as per the requirement
df_result = (df
.groupby(['Sector', 'Industry'])
.agg({'Employees': ['sum', 'mean'],
'Revchange': ['min', 'max']})
.astype(int)
.pipe(return_non_hierarchial))
# print the data
df_result.head(15)
输出:
方法2:
Pandas已经引入了命名聚合对象来创建非层次化的列。我将使用上面提到的相同需求,并将其应用于命名聚合。
这个groupby方法的语法如下。
df.groupby([‘grouping column1′,’ grouping column2”]).agg({ ‘Named column’ = NamedAgg(column=’aggregate column’, aggfunc=’aggregate function’))
实现:
"""
Program: For each "Sector" and "Industry" Find the total, average employees, and the minimum, maximum revenue change.
"""
import pandas as pd
# load the dataset with rank as index
df = pd.read_csv(
"https://raw.githubusercontent.com/sasankac/TestDataSet/master/Fortune500.csv", index_col="Rank")
# remove unwanted columns
remove_columns = ['Website', 'Hqaddr', 'Hqzip', 'Hqtel', 'Ceo',
'Ceo-title', 'Address', 'Ticker', 'Prftchange',
'Assets', 'Totshequity']
df = df.drop(columns=remove_columns, axis=1)
# Identify the data as per the requirement
df_result = (df
.groupby(['Sector', 'Industry'])
.agg(Employees_sum=pd.NamedAgg(column='Employees', aggfunc='sum'),
Employees_average=pd.NamedAgg(
column='Employees', aggfunc='mean'),
Revchange_minimum=pd.NamedAgg(
column='Revchange', aggfunc='min'),
Revchange_maximum=pd.NamedAgg(column='Revchange', aggfunc='max'))
.astype(int))
# print the data
df_result.head(15)
输出: