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

Pandas数据处理:去引号、匹配查询结果并实现行内去重

问题需求

我有一个大型Pandas DataFrame,其中names列的值被双引号包裹,部分行包含逗号分隔的多值。需要完成以下操作:

  • 移除names列的引号
  • 将每个名称的查询结果按原行对应放入新列query_result_fav_color,多值用逗号分隔
  • 每行的查询结果需去重
    无需协助实现查询逻辑,仅解决引号去除、结果正确映射及行内去重问题

简化原始数据集

ID1     ID2       names         
 01      01         "John"         
 01      02         "Kate, Ashten"       
 01      03        
 01      04         "Emily, Cathy, Joy"       

期望数据集

ID1     ID2       names                  query_result_fav_color         
 01      01         "John"                    "pink"    
 01      02         "Kate, Ashten"            "blue"
 01      03
 01      04         "Emily, Cathy, Joy"       "red, green, blue"

已尝试的方法

values=original_df['names'] # series 
values=values.to_frame()
values = values.apply(lambda x: x.str.replace('"',''))

# 执行查询(得到'results'列表)
results= ["pink", "blue", "blue", "NA", "red", "green", "blue"]

# 将查询结果放入对应行的新列(需协助)
# 得到的中间结果:
#  ID1     ID2       names                  query_result_fav_color         
# 01      01         "John"                    "pink"    
# 01      02         "Kate, Ashten"            "blue", "blue"
# 01      03                                   "NA"
# 01      04         "Emily, Cathy, Joy"       "red", "green", "blue"

# 移除行内重复值,并确保结果仅外层带引号(需协助)

补充说明

尝试过以下代码,在样本数据中有效,但实际大型数据集出现结果重复、映射错误的问题:

df = df.assign(names = df["names"].str.split(",")).explode(column="names").assign(query_result_fav_color=results).groupby(["ID1", "ID2"])["names", "query_result_fav_color"].agg(list)

df.assign(
    names=df["names"].apply(lambda x: ", ".join(x) if x else ""),
    query_result_fav_color=df["query_result_fav_color"].apply(lambda x: ", ".join(x))
).reset_index()

实际数据集错误结果(重点关注3-5行):

ID1 ID2 names               query_result_fav_color
0   01  01  John                pink
1   01  02  Kate, Ashton        blue, blue
2   01  03                      NA
3   01  04  Emily, Cathy, Joy   red, red, red
4   01  05  Jason               green
5   01  06                      blue  

解决方案

步骤1:预处理names列,去除引号并拆分

先清理names列的引号,再将每行的名称拆分为列表,同时记录每行对应的名称数量,确保后续结果映射准确:

import pandas as pd

# 复制原始数据避免修改原表
df = original_df.copy()

# 去除引号,处理空值
df['clean_names'] = df['names'].str.replace('"', '', regex=False).fillna('')

# 拆分名称为列表,空值转为空列表
df['name_list'] = df['clean_names'].apply(lambda x: [name.strip() for name in x.split(',')] if x else [])

# 计算每行的名称数量,用于后续结果切片
df['name_count'] = df['name_list'].apply(len)

步骤2:正确映射查询结果到每个名称

根据每行的名称数量,将results列表按顺序分配到对应的行:

# 初始化结果列表指针
ptr = 0
row_results = []

for cnt in df['name_count']:
    if cnt == 0:
        # 空行取对应结果
        row_results.append([results[ptr]])
        ptr += 1
    else:
        # 取对应数量的结果
        row_results.append(results[ptr:ptr+cnt])
        ptr += cnt

# 将结果存入DataFrame
df['raw_results'] = row_results

步骤3:行内去重并格式化结果

对每行的查询结果去重,再格式化为逗号分隔的字符串,同时保留外层引号:

# 行内去重,保持原始顺序
df['unique_results'] = df['raw_results'].apply(lambda x: list(dict.fromkeys(x)))

# 格式化为带外层引号的字符串,空值处理为""
df['query_result_fav_color'] = df['unique_results'].apply(
    lambda x: f'"{", ".join(x)}"' if x else ""
)

# 还原原始names列(如果需要保留原格式),或者替换为清理后的names
# 这里保留原始names列,若需要替换为无引号的列,可改为df['names'] = df['clean_names']

步骤4:整理最终数据集

删除中间辅助列,得到最终结果:

final_df = df.drop(['clean_names', 'name_list', 'name_count', 'raw_results', 'unique_results'], axis=1)
print(final_df)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 07:45:33