优化Python代码:从DataFrame字典列表提取provider生成新列
需求与优化目标
给定包含response_value和response_errors列的DataFrame,其中response_errors字段为字典列表。需提取每行中所有字典的provider键值,组成列表存入新列(示例:行1为[shipt],行2为[shipt],行3为[doordash, pickupnow, roadie])。已完成JSON预处理代码,需优化自定义traverse_dsp函数的执行效率。
已完成的预处理代码
def parse_json(webhook_data): try: data = json.loads(webhook_data) except ValueError as ex: data={'estimate':'error'} return data data_metering['RESPONSE_ERRORS']=data_metering['RESPONSE_ERRORS'].apply(parse_json)
原自定义函数(待优化)
def traverse_dsp(data_frame,column): provider = [] #Iterate over each row in Dataframe for index, row in data_frame.iterrows(): # Iterate over each json object in each row in DataFrame for i in range(0,len(row[column])): for k,v in row[column][i].items(): if k=="provider": provider_val=v x.loc[index,"provider_list"]=provider x=data_metering traverse_dsp(x,"RESPONSE_ERRORS")
优化方案
方案1:apply+列表推导(简洁高效)
直接对目标列使用apply,通过列表推导提取每行的provider值,同时处理异常情况:
def extract_providers(errors_list): # 处理非列表的异常情况(比如预处理返回的error字典) if not isinstance(errors_list, list): return [] # 提取存在的provider值,过滤空值 return [d.get('provider') for d in errors_list if d.get('provider') is not None] data_metering['provider_list'] = data_metering['RESPONSE_ERRORS'].apply(extract_providers)
方案2:匿名函数+map(极简写法)
如果逻辑简单,可直接用匿名函数实现:
data_metering['provider_list'] = data_metering['RESPONSE_ERRORS'].map( lambda x: [d.get('provider') for d in x if isinstance(x, list) and d.get('provider')] )
方案3:向量化处理(超大数据集推荐)
针对百万级以上数据集,用explode+分组聚合实现向量化操作,彻底避免逐行遍历:
# 将列表展开为多行,保留原索引 exploded_df = data_metering.explode('RESPONSE_ERRORS').reset_index() # 提取每行的provider值 exploded_df['provider'] = exploded_df['RESPONSE_ERRORS'].apply(lambda d: d.get('provider')) # 按原索引分组,聚合为列表 data_metering['provider_list'] = exploded_df.groupby('index')['provider'].agg(list).fillna([])
原函数的问题说明
iterrows()性能低下:逐行遍历是pandas中效率最低的操作之一,大数据集下耗时会呈指数增长。- 嵌套循环冗余:无需遍历字典所有键值对,直接用
d.get('provider')即可定位目标值,减少不必要的循环。 - 赋值逻辑错误:原函数未正确收集每行的多个
provider值,赋值语句x.loc[index,"provider_list"]=provider不符合需求。
内容的提问来源于stack exchange,提问作者lifo
相关产品推荐
相关产品推荐

