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

如何更高效地在Python中转换生成目标DataFrame?

宽表转长表的高效Pandas实现方案

需求说明

我有一组需要转换的数据,原始数据结构如下(实际数据集包含更多列,此处简化展示):

原始数据

lVoterUniqueIDsElectionAbbr1sElectionAbbr2sElectionAbbr3sElectionAbbr4sElectionAbbr5
3715272024PR2022Gen2022PR2020GEN2020PR
18439492024PRnullnullnullnull
28133982024PR2022Gennull2020GEN2020PR

需要完成两个核心转换:

  • 将lVoterUniqueID重命名为ID
  • 将所有sElectionAbbr[X]列合并为单一的Election_Code列,剔除空值并去重

期望输出示例

IDElection_Code
3715272024PR
18439492024PR
3715272022Gen
3715272022PR
28133982022Gen
......

现有实现方式

SQL实现

通过多次UNION拼接结果:

select distinct 
lVoterUniqueID,
sElectionAbbr1 as Election_Code
from data_set
where sElectionAbbr1 != ''
union 
select distinct 
lVoterUniqueID,
sElectionAbbr2
from data_set
where sElectionAbbr2 != ''
union ...

现有Python代码

已用Pandas实现,但过程繁琐:

import pandas as pd

df = pd.read_csv([path to data file])
# 筛选选举相关列
selected_columns = [column for column in df.columns if column.startswith("sElection")]
# 添加选民ID列
selected_columns.insert(0,'lVoterUniqueID')

# 创建空的结果DataFrame
rcdp_voters_prod = pd.DataFrame(columns=['ID','Election_Code'])

def access_elements(list_var, list_index):
    # 根据索引提取列表元素
    result = [list_var[i] for i in list_index]
    return result

# 获取选举列的索引
python_indices  = [index for (index, item) in enumerate(selected_columns) if item != "lVoterUniqueID"]

union_dict = {}

# 构建每个选举列与ID列的组合
for index in python_indices:
    union_dict.update({index:access_elements(selected_columns,[0,index])})

dataframe_list = []

# 逐个处理列组合,去重、重命名后存入列表
for key in union_dict:
    loop_df = df.filter(items=union_dict[key]).drop_duplicates()
    loop_df.rename(columns={'lVoterUniqueID':'ID',union_dict[key][1]:'Election_Code'}, inplace= True)
    dataframe_list.append(loop_df)

# 合并所有DataFrame
final_frame_form = pd.concat(dataframe_list)
# 剔除选举编码为空的行
final_frame_form=final_frame_form[final_frame_form['Election_Code'].notnull()]

更高效的Python实现方法

利用Pandas内置的melt函数(专门处理宽表转长表的向量化操作),可以大幅简化代码并提升性能:

import pandas as pd

df = pd.read_csv([path to data file])

# 核心转换:宽表转长表
result = df.melt(
    id_vars=['lVoterUniqueID'],  # 保留的标识列
    value_vars=[col for col in df.columns if col.startswith('sElection')],  # 需要转换的选举列
    value_name='Election_Code'  # 转换后的值列名
)

# 后续处理:重命名、去重、剔除空值
result = result.rename(columns={'lVoterUniqueID': 'ID'}) \
               .drop_duplicates() \
               .dropna(subset=['Election_Code'])

# 若原数据中空值以空字符串形式存在,可添加此过滤
# result = result[result['Election_Code'] != '']

代码说明

  1. melt函数:一步完成原代码中循环列组合、合并DataFrame的工作,是Pandas原生的向量化操作,处理大规模数据时效率远高于手动循环。
  2. 逻辑清晰:后续仅需执行重命名、去重、空值剔除三个步骤,代码可读性大幅提升。
  3. 兼容性强:自动适配任意数量的sElectionAbbr[X]列,无需修改代码即可处理扩展后的数据集。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 00:12:17