pivot_table多层级&单层级问题及多层级转化为单层级

193 阅读4分钟

pivot_tablevalues 参数的使用会影响生成的 DataFrame 的列层级。具体来说,values 参数的不同传递方式会导致不同的列层级。下面详细解释一下 values='price'values=['price'] 之间的区别。

1. values='price'

当你在 pivot_table 中使用单一的列名作为 values 参数时:

pivot_df = df.pivot_table(index='url', columns='date', values='price', aggfunc='first')
  • values 是单一列values='price' 表示你只对 price 列进行透视操作。这种情况下,生成的 DataFrame 的列层级是单级的,列名是日期(date 列中的值),并且它们会作为单级列名直接显示。

  • 列层级:生成的 DataFrame 只有一个级别的列。列标签是从 date 列的不同值中得出的。

2. values=['price']

当你在 pivot_table 中使用列表作为 values 参数时:

pivot_df = df.pivot_table(index='url', columns='date', values=['price'], aggfunc='first')
  • values 是列列表values=['price'] 表示你可以传递一个或多个列名列表。在这种情况下,pivot_table 会为每个 values 列创建一个新的列层级。即使你只有一个列名(例如 price),它也会被认为是多级列结构的一部分,因为它被放置在列表中。

  • 列层级:生成的 DataFrame 列会有两个层级。第一个层级是 values 列的名称(在这种情况下是 price),第二个层级是 date 列中的日期值。具体来说,列标签的结构将是 (values, date) 形式的 MultiIndex。

具体示例

假设原始 DataFrame df 如下:

import pandas as pd

# 示例数据
data = {
    'url': ['url1', 'url1', 'url2', 'url2'],
    'date': ['2024W30', '2024W31', '2024W30', '2024W31'],
    'price': [100, 200, 150, 250]
}

df = pd.DataFrame(data)

示例 1: 单一列名

pivot_df_1 = df.pivot_table(index='url', columns='date', values='price', aggfunc='first')
print(pivot_df_1)

输出:

date     2024W30  2024W31
url                         
url1        100.0    200.0
url2        150.0    250.0
  • 这里的列是单级的,直接来自 date 列的不同值。

示例 2: 列名列表

pivot_df_2 = df.pivot_table(index='url', columns='date', values=['price'], aggfunc='first')
print(pivot_df_2)

输出:

         price       
date  2024W30 2024W31
url                     
url1    100.0   200.0
url2    150.0   250.0
  • 这里的列是多级的,第一层级是 values 列名(price),第二层级是 date 列中的日期值。

总结

  • values='price':生成单级列 DataFrame。列标签是 date 列中的不同值。
  • values=['price']:生成多级列 DataFrame。列标签有两个层级,第一个层级是 values 中的列名(price),第二个层级是 date 列中的不同值。

这个差异主要是由于 values 参数的不同形式导致的。如果你只需要一个平面结构的 DataFrame,使用单一列名作为 values 是最简单的方式。如果你需要多个列的层级或更复杂的列结构,可以使用列名列表。

当你使用 Pandas 的 pivot_table 创建多级列(MultiIndex)时,你可能需要将这些多级列展平为单级列。下面是如何通过示例详细说明这一转换过程。

示例数据

首先,创建一个带有多级列的透视表:

import pandas as pd

# 示例数据
data = {
    'url': ['url1', 'url1', 'url2', 'url2'],
    'date': ['2024W30', '2024W31', '2024W30', '2024W31'],
    'price': [100, 200, 150, 250],
    'entityStatus': ['active', 'inactive', 'active', 'inactive']
}

df = pd.DataFrame(data)

# 创建透视表,values 为多个列
pivot_df = df.pivot_table(index='url', columns='date', values=['price', 'entityStatus'], aggfunc='first')

print(pivot_df)

原始透视表输出

              entityStatus                price          
date                2024W30 2024W31 2024W30 2024W31
url                                                  
url1                   active inactive     100.0   200.0
url2                   active inactive     150.0   250.0

在这个透视表中,列有两个层级:

  1. 第一层级是 entityStatusprice
  2. 第二层级是不同的 date 值(例如 2024W302024W31)。

展平多级列

要将这些多级列展平为单级列,可以使用以下代码:

# 展平列名
pivot_df.columns = ['_'.join(col).strip() if isinstance(col, tuple) else col for col in pivot_df.columns]

print(pivot_df)

展平后的 DataFrame 输出

        entityStatus_2024W30  entityStatus_2024W31  price_2024W30  price_2024W31
url                                                                              
url1                    active                inactive         100.0         200.0
url2                    active                inactive         150.0         250.0

解释

  • 原始透视表:列有两个层级,第一层级是 entityStatusprice,第二层级是日期(2024W302024W31)。
  • 展平操作pivot_df.columns 是一个多级列索引。在展平过程中:
    • ['_'.join(col).strip() if isinstance(col, tuple) else col for col in pivot_df.columns] 将每个多级列索引展平为一个单级列名。
    • 对于每个列元组(例如 ('price', '2024W30')),使用 '_' 将它们连接成一个字符串(例如 'price_2024W30')。
    • strip() 去除可能的多余空格。