本文将围绕以下步骤展开,解决如何合并 DataFrame 中具有成对属性名称和属性值的列,特别是当属性值列可能包含列表的情况:
- 提取列名信息:利用 Pandas 的 extract 函数从列名中提取关键信息,构建 MultiIndex。
- 重塑 DataFrame:使用 stack 函数将 DataFrame 重塑为更适合处理的格式。
- 重命名列并添加前缀:为了清晰起见,重命名列并为列名添加 "Attribute " 前缀。
- 分割属性值:使用 split 函数将包含逗号分隔值的属性值列分割成列表。
- 展开列表:使用 explode 函数将列表展开为单独的行,从而得到最终的 DataFrame。
详细步骤及代码示例
假设我们有以下 DataFrame,需要将其转换为目标格式:
import pandas as pd
data = {'Title': ['Title 1', 'Title 2'],
'Description': ['Desc 1', 'Desc 2'],
'Attribute 1 name': ['Sport', 'Size'],
'Attribute 1 value': ['NFL', 'Large, Medium'],
'Attribute 2 name': ['Sport', 'Sleeve Type'],
'Attribute 2 value': ['NBA', 'Long Sleeve, Short Sleeve']}
df = pd.DataFrame(data)
print(df)
输出:
Title Description Attribute 1 name Attribute 1 value Attribute 2 name \ 0 Title 1 Desc 1 Sport NFL Sport 1 Title 2 Desc 2 Size Large, Medium Sleeve Type Attribute 2 value 0 NBA 1 Long Sleeve, Short Sleeve
1. 提取列名信息
首先,使用 str.extract 函数从列名中提取数字和属性类型(name 或 value),并创建一个 MultiIndex。正则表达式 r'\S+ (\d+) (\S+)' 用于匹配列名中的模式,其中 \S+ 匹配一个或多个非空白字符,(\d+) 匹配一个或多个数字,(\S+) 匹配一个或多个非空白字符。
idx = pd.MultiIndex.from_frame(
df.columns
.str.extract(r'\S+ (\d+) (\S+)')
)
print(idx)
输出:
MultiIndex([( '1', 'name'),
( '1', 'value'),
( '2', 'name'),
( '2', 'value')],
)
2. 重塑 DataFrame
使用 set_axis 函数将创建的 MultiIndex 应用于 DataFrame 的列,然后使用 stack 函数将 DataFrame 从宽格式转换为长格式。stack(0) 将 MultiIndex 的第一层(即数字)堆叠到行索引中。
out = (df.set_axis(idx, axis=1).stack(0)
.rename_axis(columns=None)
.add_prefix('Attribute ')
.sort_index(level=-1)
)
print(out)
输出:
Attribute name Attribute value 0 Sport NFL 1 Size Large, Medium 0 Sport NBA 1 Sleeve Type Long Sleeve, Short Sleeve
3. 分割属性值并展开列表
使用 str.split(', *') 将 "Attribute value" 列中的逗号分隔值分割成列表。然后,使用 explode 函数将列表展开为单独的行。explode('Attribute value', ignore_index=True) 将 "Attribute value" 列中的每个列表展开为多行,并重置索引。
out = (df.set_axis(idx, axis=1).stack(0)
.rename_axis(columns=None)
.add_prefix('Attribute ')
.sort_index(level=-1)
.assign(**{'Attribute value': lambda d: d['Attribute value'].str.split(', *')})
.explode('Attribute value', ignore_index=True)
)
print(out)
输出:
Attribute name Attribute value 0 Sport NFL 1 Size Large 2 Size Medium 3 Sport NBA 4 Sleeve Type Long Sleeve 5 Sleeve Type Short Sleeve
总结
通过结合使用 extract、stack、split 和 explode 等 Pandas 函数,我们可以有效地处理包含列表的 DataFrame 列合并问题。这种方法不仅简洁,而且易于理解和维护。
注意事项:
- 在实际应用中,请根据实际数据调整正则表达式
r'\S+ (\d+) (\S+)',以确保正确提取列名信息。 - 如果 DataFrame 包含大量列,
stack操作可能会消耗大量内存。在这种情况下,可以考虑使用分块处理或其他优化技术。 - 在调用
explode之前,请确保要展开的列确实包含列表。否则,explode操作可能会导致意外的结果。










