You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

根据映射表拆分Pandas DataFrame时遇'unhashable type: list'错误求助

问题描述

我有一个包含200+列的客户数据DataFrame(df),其中包含CAMPAIGN_ID列;另有映射表mapping_csv,记录每个CAMPAIGN_ID对应的需提取列列表。我需要按CAMPAIGN_ID拆分df,为每个campaign生成仅包含对应映射列的CSV文件,但运行代码时触发「TypeError: unhashable type: 'list'」错误。

尝试的代码如下:

for campaign in df['CAMPAIGN_ID'].unique():
  df2 = df[df['CAMPAIGN_ID']==campaign]
  # remove blank columns
  df2.dropna(how='all', axis=1, inplace=True)
  for column in df2.columns:
    if df2[column].unique()[0]=="0000-00-00" and df2[column].unique().shape[0]==1:
      df2 = df2.drop(column, axis=1)
  for column in df2.columns:
    if df2[column].unique()[0]=='0' and df2[column].unique().shape[0]==1:
      df2 = df2.drop(column, axis=1)
  # select required columns
  df2 = df2[mapping_csv.loc[mapping_csv['CAMPAIGN_ID']==campaign, 'Variable_List'].str.replace(" ","").str.split(",")]
  file_shape = df2.shape[0]
  filename = "cart_"+str(dt.date.today().strftime('%Y%m%d'))+"_"+campaign+"_rowcnt_"+str(file_shape) 
  df2.to_csv(filename+".csv",index=False)
错误原因

报错「TypeError: unhashable type: 'list'」是因为mapping_csv.loc[mapping_csv['CAMPAIGN_ID']==campaign, 'Variable_List'].str.replace(" ","").str.split(",")返回的是包含列表元素的Series对象,而DataFrame索引列时需要的是可哈希的一维列表/数组,直接用这个Series索引就会触发错误。

修正方案

需要把提取到的列列表从Series中取出,确保是一维列表类型;同时可以提前预处理映射表,避免循环内重复计算,还能优化空列删除逻辑。

修正后的代码:

import pandas as pd
import datetime as dt

# 提前预处理映射表,转成字典快速查找
mapping_csv['Variable_List'] = mapping_csv['Variable_List'].str.replace(" ", "").str.split(",")
campaign_cols_map = mapping_csv.set_index('CAMPAIGN_ID')['Variable_List'].to_dict()

for campaign in df['CAMPAIGN_ID'].unique():
    # 筛选当前campaign数据,用copy避免链式赋值警告
    df2 = df[df['CAMPAIGN_ID'] == campaign].copy()
    
    # 批量筛选需要删除的列:空列、全为"0000-00-00"、全为"0"的列
    drop_cols = []
    for col in df2.columns:
        unique_vals = df2[col].unique()
        if (df2[col].isna().all() 
            or (len(unique_vals) == 1 and unique_vals[0] == "0000-00-00") 
            or (len(unique_vals) == 1 and unique_vals[0] == '0')):
            drop_cols.append(col)
    df2.drop(drop_cols, axis=1, inplace=True)
    
    # 获取当前campaign的目标列,过滤df2中不存在的列
    target_cols = campaign_cols_map.get(campaign, [])
    valid_cols = [col for col in target_cols if col in df2.columns]
    
    if valid_cols:
        df2 = df2[valid_cols]
        row_count = df2.shape[0]
        filename = f"cart_{dt.date.today().strftime('%Y%m%d')}_{campaign}_rowcnt_{row_count}"
        df2.to_csv(f"{filename}.csv", index=False)
    else:
        print(f"Campaign {campaign} 无匹配有效列,跳过导出")
关键改进点
  • 提前将映射表转为字典,减少循环内重复计算,提升运行效率
  • 合并列删除逻辑为一次循环,减少对DataFrame列的遍历次数
  • 确保目标列是一维列表,避免Series引发的哈希错误
  • 添加列存在性检查,避免因映射列不存在触发KeyError
  • 使用f-string格式化字符串,代码更简洁易读

内容的提问来源于stack exchange,提问作者Prasanjit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 22:40:31