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

求Pandas低时间复杂度实现DataFrame跨行条件更新的最优方案

问题描述

我有一个包含350万条(行)网页爬取数据的Pandas DataFrame。其中R公司的数据干净规范,M公司的数据则不然。需要将所有M公司的文章中,同时存在于R公司的文章对应的brand、category、series字段替换为R公司的对应值,但当前运行代码耗时过长,求时间复杂度最低的Pandas解决方案。

原始代码
import pandas as pd
    
d = {
    'company': [
        'R', 
        'R',
        'M',
        'M',
        'M',
        'G'
        ],
    'article': [
        'a',
        'b',
        'a',
        'a',
        'c',
        'a'
         ],
    'brand': [
        'brand1',
        'brand1',
        'brand1x',
        'brand1x',
        'brand1x',
        'brand'
        ],
    'category':[
        'cat',
        'cat',
        'catx',
        'catx',
        'catx',
        'cat'
        ],
    'series':[
        'series1',
        'series1',
        'series1x',
        'series1x',
        'series1x',
        'series'
        ],
    'price':[
        2,
        2.2,
        2.25,
        2.27,
        2.27,
        '',
        ],
    'date':[
        '2023-11-05',
        '2023-11-11',
        '2023-11-05',
        '2023-11-11',
        '2023-11-11',
        ''
        ],
    }
    
df = pd.DataFrame(data=d)

# 创建仅包含R公司数据且去重的DataFrame
selected_columns = df[df['company'] == 'R'][['article', 'brand', 'category', 'series']].drop_duplicates()

# 定义更新字段的函数
def update_values(row):
    article = row['article']
    if article in selected_columns['article'].values:
        selected_row = selected_columns[selected_columns['article'] == article]
        row['brand'] = selected_row['brand'].values[0]
        row['category'] = selected_row['category'].values[0]
        row['series'] = selected_row['series'].values[0]
    return row

# 对M公司数据应用更新函数
new = df[df['company'] == 'M'].apply(update_values, axis=1)

# 筛选出R公司数据
df = df[df['company'] == 'R']

# 合并结果
frames = [new,df]
df = pd.concat(frames)
原始代码的问题

原始代码使用apply逐行处理M公司数据,本质是Python层面的循环,在350万行的数据集上会非常耗时——虽然时间复杂度是O(n),但常数项极大,完全没利用Pandas的向量化运算优势。

优化方案(时间复杂度最优)

核心思路是利用Pandas的向量化操作和索引映射,彻底避免逐行循环:

  1. 提取R公司的唯一文章-规范字段映射表,以article为索引,确保每个article只对应一组规范值
  2. 用掩码筛选出需要更新的M公司行(即article存在于R公司映射表中的行)
  3. 批量替换这些行的目标字段
优化后的代码
import pandas as pd

d = {
    'company': ['R', 'R', 'M', 'M', 'M', 'G'],
    'article': ['a', 'b', 'a', 'a', 'c', 'a'],
    'brand': ['brand1', 'brand1', 'brand1x', 'brand1x', 'brand1x', 'brand'],
    'category': ['cat', 'cat', 'catx', 'catx', 'catx', 'cat'],
    'series': ['series1', 'series1', 'series1x', 'series1x', 'series1x', 'series'],
    'price': [2, 2.2, 2.25, 2.27, 2.27, ''],
    'date': ['2023-11-05', '2023-11-11', '2023-11-05', '2023-11-11', '2023-11-11', '']
}

df = pd.DataFrame(data=d)

# 1. 创建R公司的文章-规范字段映射表,以article为索引并去重
r_mapping = df[df['company'] == 'R'][['article', 'brand', 'category', 'series']].drop_duplicates().set_index('article')

# 2. 复制原DataFrame避免修改原始数据
df_updated = df.copy()

# 3. 生成需要更新的行的掩码:M公司且article在R的映射表中
update_mask = (df_updated['company'] == 'M') & (df_updated['article'].isin(r_mapping.index))

# 4. 批量更新指定字段(向量化操作,效率极高)
df_updated.loc[update_mask, 'brand'] = df_updated.loc[update_mask, 'article'].map(r_mapping['brand'])
df_updated.loc[update_mask, 'category'] = df_updated.loc[update_mask, 'article'].map(r_mapping['category'])
df_updated.loc[update_mask, 'series'] = df_updated.loc[update_mask, 'article'].map(r_mapping['series'])

# 查看结果
print(df_updated)
预期输出
d = {
    'company': ['R', 'R', 'M', 'M', 'M', 'G'],
    'article': ['a', 'b', 'a', 'a', 'c', 'a'],
    'brand': ['brand1', 'brand1', 'brand1', 'brand1', 'brand1x', 'brand'],
    'category': ['cat', 'cat', 'cat', 'cat', 'catx', 'cat'],
    'series': ['series1', 'series1', 'series1', 'series1', 'series1x', 'series'],
    'price': [2, 2.2, 2.25, 2.27, 2.27, ''],
    'date': ['2023-11-05', '2023-11-11', '2023-11-05', '2023-11-11', '2023-11-11', '']
}
print(pd.DataFrame(d))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 17:03:12