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

为何Pandas中apply会破坏category类型而for循环不会?最优写法探讨

Pandas中整行apply破坏Category类型的原因及解决方案

问题复现

初始创建带有Category类型列的DataFrame:

import pandas as pd
df = pd.DataFrame({"A": ['Apple','Strawberry','Cherry'],"B":['yes','yes','no'],"C":['green','red','red']})
df.B = df.B.astype("category")
df_cpy = df.copy()
  1. for循环修改(保留Category类型)
    仅修改C列,未改动的B列仍保持Category类型:
for i, row in df.iterrows():
    if row["C"] == 'green':
        df.at[i, 'C'] = 'yellow'
  1. 整行apply修改(破坏Category类型)
    处理整行后,原本的Category列B会变为object类型:
def changer(row):
    if row["C"] == 'green':
        row["C"] = 'yellow'
    return row
df_cpy = df_cpy.apply(changer, axis='columns')
  1. 针对单列的apply(保留Category类型)
    仅对C列使用apply,B列的Category类型不受影响:
df["C"] = df.apply(lambda x: 'yellow' if x["C"] == 'green' else x["C"], axis=1)

核心原因

  • for循环+at修改:属于原地修改,仅对目标列C的指定行进行值替换,其他列(如B)完全未被触碰,因此其Category类型保持不变。
  • 整行apply:apply(axis='columns')会逐行将DataFrame的行转换为Series进行处理。当你从DataFrame中取出一行时,该行的Category列元素是普通标量值(而非带有Category类型标记的对象),处理后返回的Series中,B列的元素已经是普通字符串。当pandas将所有处理后的行Series拼接成新DataFrame时,会自动推断列类型,此时B列会被识别为object类型,丢失原有的Category信息。
  • 单列apply:仅针对C列进行操作,直接替换C列的值,其他列完全未被操作,因此B列的Category类型得以保留。

多列修改时保留Category类型的最优写法

优先使用向量化操作,这类操作不仅效率远高于循环或整行apply,还能完美保留原有列的类型:

1. 原地批量修改(loc)

适合需要直接修改原DataFrame的场景,可同时修改多列:

# 示例:当C列为green时,修改C为yellow,同时修改A为'Yellow Apple'
df.loc[df['C'] == 'green', ['C', 'A']] = ['yellow', 'Yellow Apple']

2. 创建新DataFrame(assign)

适合不希望修改原DataFrame的场景,链式调用更清晰:

import numpy as np

df_new = df.assign(
    C=np.where(df['C'] == 'green', 'yellow', df['C']),
    A=np.where(df['C'] == 'green', 'Yellow Apple', df['A'])
)

3. 针对多列的自定义函数(复杂逻辑场景)

如果修改逻辑复杂,无法用简单的向量化操作实现,可针对列单独使用apply,避免整行处理:

def modify_c(c_val):
    return 'yellow' if c_val == 'green' else c_val

def modify_a(a_val, c_val):
    return 'Yellow Apple' if c_val == 'green' else a_val

df['C'] = df['C'].apply(modify_c)
df['A'] = df.apply(lambda x: modify_a(x['A'], x['C']), axis=1)

这种方式仅修改目标列,其他列(如B)的Category类型不受影响。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 20:18:19