读取CSV时Pandas字符串列重赋值报错,读取XLSX则正常
问题原因及解决办法
核心差异:两种字符串存储类型的区别
你碰到的问题根本原因是:CSV读出来的value列是Pandas的强类型StringDtype,而XLSX读出来的列是弱类型的object dtype——哪怕你用df.dtypes看都是"string",但底层逻辑完全不一样:
- 强类型
StringDtype(底层是StringArray):这是Pandas 1.0之后新增的专门字符串类型,限制严格,只能存储字符串值。你往里面塞整数0、布尔值True这类非字符串时,会直接抛出ValueError(就是你遇到的报错)。Pandas 1.5.x版本读取CSV时,若检测到列全为字符串,会自动推断为该类型。 - 弱类型
objectdtype:本质是存储Python对象的数组,允许混合存储不同类型的值。sxl库读取XLSX生成的DataFrame列默认就是这个类型,哪怕列内全是字符串,有时df.dtypes的显示会让你误以为是string,但实际是object,所以替换非字符串值不会报错。
为啥同事运行无报错?
大概率是同事的Pandas版本低于1.0,旧版本没有专门的StringDtype,所有字符串列都是object dtype,自然允许插入非字符串值;也有可能他读取CSV时没有触发StringDtype的自动推断逻辑。
可选解决办法(除了你已经用的astype('object'))
- 读取CSV时直接指定
object类型:
直接将列读取为df_csv = pd.read_csv('你的文件.csv', dtype={'value': 'object'})objectdtype,避开强类型的StringArray限制。 - 把替换值转成字符串再赋值:
若想保留StringDtype,可以将替换目标值转为字符串:df_csv["value"] = df_csv["value"].replace({"A": "0", "B": "1"}) - 先转类型再替换:
即你已使用的方法,将StringDtype转为object后再执行替换:df_csv["value"] = df_csv["value"].astype('object').replace({"A": 0, "B": 1})
内容的提问来源于stack exchange,提问作者butterflyeffect
相关产品推荐
相关产品推荐

