如何使用pd.melt将含前缀分组列的DataFrame逆透视?
拆分商家评论数据的逆透视解决方案
针对你需要将每行商家的多条评论拆分为单独行的需求,这里提供两种高效的实现方法,替代直接使用pd.melt的繁琐操作:
方法一:使用pd.wide_to_long(推荐,更高效)
该方法适配列名有结构化规律的场景,你的reviews/n/xxx格式正好匹配:
步骤示例
import pandas as pd # 构造示例数据(实际使用时替换为你的DataFrame) data = { 'business_id': ['12345'], 'address': ['01 street'], 'reviews/0/date': ['1/1/1990'], 'reviews/0/text': ['"abc"'], 'reviews/1/date': ['2/2/1995'], 'reviews/1/text': ['"def"'] } df = pd.DataFrame(data) # 重命名评论列,将reviews/n/xxx转为reviews_xxx_n格式,适配wide_to_long df.columns = [ col.replace('reviews/', 'reviews_').replace('/', '_') if 'reviews/' in col else col for col in df.columns ] # 执行逆透视 result = pd.wide_to_long( df, stubnames=['reviews_date', 'reviews_text'], # 评论属性的前缀 i=[col for col in df.columns if not col.startswith('reviews_')], # 保留的商家信息列 j='review_number', # 生成的评论编号列名 sep='_', suffix=r'\d+' # 匹配评论编号的数字 ).reset_index() # 重命名列到目标格式 result = result.rename(columns={ 'reviews_date': 'review_date', 'reviews_text': 'review_text' }) print(result)
方法二:先melt再拆分列名
如果不想修改列名,可以用这种分步处理的方式:
步骤示例
import pandas as pd # 同样使用示例数据 data = { 'business_id': ['12345'], 'address': ['01 street'], 'reviews/0/date': ['1/1/1990'], 'reviews/0/text': ['"abc"'], 'reviews/1/date': ['2/2/1995'], 'reviews/1/text': ['"def"'] } df = pd.DataFrame(data) # 筛选商家信息列(所有不以reviews/开头的列) id_vars = [col for col in df.columns if not col.startswith('reviews/')] # 先将所有评论列转为长格式 melted = df.melt(id_vars=id_vars, var_name='review_col', value_name='value') # 拆分评论列名,提取评论编号和属性 melted[_, 'review_number', 'attribute'] = melted['review_col'].str.split('/', expand=True) # 去掉无用的前缀列,将属性转为列 result = melted.pivot_table( index=['business_id', 'address', 'review_number'], columns='attribute', values='value', aggfunc='first' ).reset_index() # 重命名列到目标格式 result = result.rename(columns={ 'date': 'review_date', 'text': 'review_text' }) print(result)
注意事项
- 确保所有评论列的格式统一为
reviews/n/属性,避免格式错误导致拆分失败 - 如果存在空的评论值,处理后会出现NaN,可根据需求用
result.dropna()删除无效行 - 商家信息列要准确筛选,确保所有非评论相关的列都被包含在
id_vars中
内容的提问来源于stack exchange,提问作者raz
相关产品推荐
相关产品推荐

