pandas 如何在 read_csv 时强制某些列为 string 而非 int/float

9次阅读

最直接方法是用 dtype 参数指定列类型:dtype={“user_id”: str} 或 dtype={0: str};处理含空值的数字列时,必须同时设置 keep_default_na=False 和 na_values=None。

pandas 如何在 read_csv 时强制某些列为 string 而非 int/float

用 dtype 参数指定列类型最直接

read_csv 默认会尝试推断每列数据类型,遇到全数字就转成 intFloat。要强制某列为 String,必须显式传入 dtype 参数,值为字典:键是列名(或列索引),值是 strObject(二者在此场景下等效)。

  • 列名存在且稳定时,优先用列名:dtype={"user_id": str, "code": str}
  • 列名可能缺失或含空格,可用列索引:dtype={0: str, 2: str}
  • 若整张表都需保持原始字符串,直接用 dtype=str(但会关闭类型推断,所有列都变 object)
  • 注意:如果该列后续有 na_valueskeep_default_na=False 等设置,空值仍可能被识别为 NaN,此时列类型仍是 object,但元素混合了 strfloatNaN 是 float)——这不是你想要的,得配合 keep_default_na=False + na_values=None 控制

处理含缺失值的数字列转 string 的坑

这是最常踩的坑:一列看起来是“123”、“456”、“”,read_csv 默认把空转成 NaN,而 NaN 是浮点类型,导致即使你写了 dtype={"col": str},最终该列仍是 object 类型,但内部混着 strfloatNaN),调用 .str.upper() 会报 AttributeError

  • 正确做法是关掉默认 NaN 解析:keep_default_na=False
  • 同时清空自定义空值列表:na_values=None(否则 na_values=[""] 这类默认值仍生效)
  • 完整示例:
    pd.read_csv("data.csv", dtype={"id": str}, keep_default_na=False, na_values=None)

列名还没读出来时怎么指定 dtype?

有时 CSV 没有 header,或者 header 行本身含异常字符,你想跳过它再读,但又需要对特定位置的列设类型——这时不能靠列名,只能靠列序号。

  • header=Nonepandas 不把第一行当列名,列自动命名为 0, 1, 2…
  • 再用 dtype={1: str, 3: str} 指定第 2 列、第 4 列为 string
  • 如果还用了 skiprows=1 跳过脏 header,注意 skiprowsheader 解析前执行,列序号仍从实际读取的第一行开始计数

为什么不用 converters?

converters 看似灵活(例如 converters={"id": str}),但它是在 dtype 推断之后才执行的,属于“后处理”。这意味着:如果原列被识别为 int,而其中有非法值(如 “123abc”),read_csv 会先报错或转成 NaN,根本走不到 converters;而 dtype 是底层解析阶段控制,能避免类型冲突提前中断。

所以除非你需要做复杂转换(比如去空格+截取),否则别用 converters 强制 string——它不解决根本问题,还掩盖类型推断失败。

真正难的是混合空值和数字字符串的列,那几行配置组合(dtype + keep_default_na=False + na_values=None)缺一不可,少一个都可能让列里悄悄混进 NaN

text=ZqhQzanResources