如何扁平化Pandas DataFrame列中的分层索引
在这篇文章中,我们将看到在Pandas DataFrame列中平坦化一个分层索引。层次索引通常是作为groupby聚合函数的结果出现的。所使用的聚合函数将出现在所产生的数据框架的层次索引中。
方法1:使用reset_index()函数
Pandas提供了一个名为reset_index()的函数,用于平移由于groupby聚合函数而创建的层次索引。
语法: pandas.DataFrame.reset_index(level, drop, inplace)
参数:
- level – 只从索引中删除指定的级别
- drop – 将索引重置为默认的整数索引
- inplace – 永久地修改数据框架对象,而不创建一个副本。
示例:
在这个例子中,我们用pandas groupby函数将汽车销售数据按季度分组,用reset_index()pandas函数将分组后的数据框架的分层索引列平移。
# import the python pandas package
import pandas as pd
# create a sample dataframe
data = pd.DataFrame({"cars": ["bmw", "bmw", "benz", "benz"],
"sale_q1 in Cr": [20, 22, 24, 26],
'sale_q2 in Cr': [11, 13, 15, 17]},
columns=["cars", "sale_q1 in Cr",
'sale_q2 in Cr'])
# group by cars based on the sum
# of sales on quarter 1 and 2
grouped_data = data.groupby(by="cars").agg("sum")
print(grouped_data)
# use reset_index to flattened
# the hierarchical dataframe.
flat_data = grouped_data.reset_index()
print(flat_data)
输出:
方法2:使用as_index()函数
Pandas提供了一个名为as_index()的函数,它由一个布尔值指定。as_index()函数通过指定的聚合函数对数据框架进行分组,如果as_index()的值为假,则产生的数据框架被压扁。
语法: pandas.DataFrame.groupby(by, level, axis, as_index)
参数:
- by –指定要进行groupby操作的列
- level – 指定了要分组的列的索引
- axis – 指定是否沿着行(0)或列(1)进行分割
- as_index –返回一个以分组标签为索引的对象,用于聚合输出
示例:
在这个例子中,我们使用pandas groupby函数将汽车销售数据按季度分组,并将as_index参数提到False,并指定as_index参数为false,以确保分组后的数据框架的层次索引被扁平化。
# import the python pandas package
import pandas as pd
# create a sample dataframe
data = pd.DataFrame({"cars": ["bmw", "bmw", "benz", "benz"],
"sale_q1 in Cr": [20, 22, 24, 26],
'sale_q2 in Cr': [11, 13, 15, 17]},
columns=["cars", "sale_q1 in Cr",
'sale_q2 in Cr'])
# group by cars based on the
# sum of sales on quarter 1 and 2
# and mention as_index is False
grouped_data = data.groupby(by="cars", as_index=False).agg("sum")
# display
print(grouped_data)
输出:
方法3:使用groupby在pandas数据框架中扁平化分层索引
每当我们在一个有多个聚合函数的单列上使用groupby函数时,我们会得到基于聚合类型的多个层次索引。在这种情况下,分层索引必须在两个层次上都被平坦化。
语法: pandas.DataFrame.groupby(by=None, axis=0, level=None)
参数:
- by – 映射函数,确定groupby函数中的组。
- axis – 0 – 沿着行进行分割,1 – 沿着列进行分割。
- level – 如果轴是多索引的,在指定的级别上分组。(int)
语法: pandas.DataFrame.agg(func=None, axis=0)
参数:
- func – 指定用作聚合函数的函数。(最小、最大、总和等)
- axis – 0 – 函数应用于每一列,1-应用于每一行。
步骤:
- 导入python pandas包。
- 创建一个样本数据框架,显示q1和q2两个季度的汽车销量,如图所示。
- 现在使用pandas groupby函数,根据第1季度销售额的总和和最大值以及第2季度销售额的总和和最小值进行分组。
- 分组数据框架的多索引列存储在一个图元的列表中。使用for循环来迭代图元列表,并将它们连接成一个单一的字符串。
- 在flat_cols列表中追加加入的字符串。
- 现在将flat_cols列表分配给多索引分组数据框架列的列名。
# import the python pandas package
import pandas as pd
# create a sample dataframe
data = pd.DataFrame({"cars": ["bmw", "bmw", "benz", "benz"],
"sale_q1 in Cr": [20, 22, 24, 26],
'sale_q2 in Cr': [11, 13, 15, 17]},
columns=["cars", "sale_q1 in Cr",
'sale_q2 in Cr'])
# group by cars based on the sum and max of sales on quarter 1
# and sum and min of sales 2 and mention as_index is False
grouped_data = data.groupby(by="cars").agg({"sale_q1 in Cr": [sum, max],
'sale_q2 in Cr': [sum, min]})
# create an empty list to save the
# names of the flattened columns
flat_cols = []
# the multiindex columns of two
# levels would be stored as tuples
# iterate through this tuples and
# join them as single string
for i in grouped_data.columns:
flat_cols.append(i[0]+'_'+i[1])
# now assign the list of flattened
# columns to the grouped columns.
grouped_data.columns = flat_cols
# print the grouped data
print(grouped_data)
输出:
方法4:使用to_records()函数将分层索引扁平化
在这个例子中,我们使用了pandas数据框架的to_records()函数,它将数据框架中的所有行转换为图元数组。然后,这个图元数组被传递给pandas.DataFrame函数,将分层索引转换为扁平化的列。
语法: pandas.DataFrame.to_records(index=True, column_dtypes=None)
参数:
- index – 在结果数组中创建一个索引
- column_dtypes – 将列设置为指定的数据类型。
代码:
# import the python pandas package
import pandas as pd
# create a sample dataframe
data = pd.DataFrame({"cars": ["bmw", "bmw", "benz", "benz"],
"sale_q1 in Cr": [20, 22, 24, 26],
'sale_q2 in Cr': [11, 13, 15, 17]},
columns=["cars", "sale_q1 in Cr",
'sale_q2 in Cr'])
# group by cars based on the sum
# and max of sales on quarter 1
# and sum and min of sales 2 and mention
# as_index is False
grouped_data = data.groupby(by="cars").agg({"sale_q1 in Cr": [sum, max],
'sale_q2 in Cr': [sum, min]})
# use to_records function on grouped data
# and pass this to the Dataframe function
flattened_data = pd.DataFrame(grouped_data.to_records())
print(flattened_data)
输出:
方法5:使用join()和rstrip()将分层列扁平化
在这个例子中,我们使用join()和rstrip()函数来平整列。通常情况下,当我们将一个数据框架分组为分层索引列时,多级的列被存储为一个图元数组元素。在这里,我们通过连接每个元组的列名和索引名来迭代这些元组,并将得到的扁平化的列名存储在一个列表中。之后,这个存储的扁平化列的列表被分配到分组数据框架中。
语法: str.join(iterable)
解释: 如果可以迭代,则返回一个串联的字符串,否则返回类型错误。
语法: str.rstrip([chars])
解释: 通过分割多余的尾部空格(最右边)返回一个字符串。
代码:
# import the python pandas package
import pandas as pd
# create a sample dataframe
data = pd.DataFrame({"cars": ["bmw", "bmw", "benz", "benz"],
"sale_q1 in Cr": [20, 22, 24, 26],
'sale_q2 in Cr': [11, 13, 15, 17]},
columns=["cars", "sale_q1 in Cr",
'sale_q2 in Cr'])
# group by cars based on the sum
# and max of sales on quarter 1
# and sum and min of sales 2 and
# mention as_index is False
grouped_data = data.groupby(by="cars").agg({"sale_q1 in Cr": [sum, max],
'sale_q2 in Cr': [sum, min]})
# use join() and rstrip() function to
# flatten the hierarchical columns
grouped_data.columns = ['_'.join(i).rstrip('_')
for i in grouped_data.columns.values]
print(grouped_data)
输出: