从csv而不是xlsx读取时,Pandas字符串重新分配错误

mbyulnm0  于 2023-03-15  发布在  其他
关注(0)|答案(1)|浏览(145)

我使用panda读入两个数据集,并重新分配每个数据集的value列,一个数据集是csv,加载了pd.read_csv(),另一个数据集是xlsx,加载了来自sxl库的Workbook.sheets()
在重新赋值之前,两个value列都是string数据类型(用df.dtypes检查)。

df["value"] = df["value"].replace({"A": 0, "B": 1})

对于csv中的数据,此行将出错

ValueError: Cannot set non-string value '0' into a StringArray.

我得到了类似的错误

ValueError: Cannot set non-string value 'True' into a StringArray

当我尝试将字符串类型的列重新分配为True/False时。当我在Excel文档中的数据的值列上运行同一行时,没有错误。
我可以通过在用.astype('object')重新赋值之前强制转换值来修复这个错误,但我不确定为什么会这样--两个 Dataframe 中的value都是字符串类型。
我的同事没有得到这个错误,所以可能不需要创可贴,我运行的是Python 3.9.4、panda 1.5.3和numpy 1.22.0。

j5fpnvbx

j5fpnvbx1#

长话短说,"value"列的dtype是'string',它是一个extension dtype for string data,也可以为空,这意味着该列中的值可以是字符串或NaN,当您试图将该列中的值替换为整数("A" -> 0"B" -> 1)时,会引发错误,因为该列中的值不能为整数。
下面的代码将重现此错误:

df = pd.DataFrame({'value': ['A', 'B', 'A', 'C']}, dtype='string')
df["value"] = df["value"].replace({"A": 0, "B": 1})               # <------ error

如果替换值是字符串,则不会出现错误,即以下内容不会引发任何错误:

df["value"] = df["value"].replace({"A": '0', "B": '1'})           # <------ no error

为什么dtype=object没有引发任何错误?

Pandas对象dtype可以保存任何Python对象,换句话说,任何东西都可以放在对象dtype的列中。Python对象,如整数、字符串、浮点数、甚至列表、字典等,都可以存储在object列中。因此,在这样的列中,用整数替换字符串是没有问题的。

df1 = pd.DataFrame({'value': ['A', 'B', 'A', 'C']}, dtype=object)
df1["value"] = df1["value"].replace({"A": 0, "B": 1})             # <------ no error

但是,在这种情况下,列变成了混合列。要查看'value'列中作为Python对象的值,请对该列调用tolist()

df['value'].tolist()         # ['0', '1', '0', 'C']         <------ all strings
df1['value'].tolist()        # [0, 1, 0, 'C']               <------ integers and strings

注意dtype=str也将列dtype转换为object(但值实际上是字符串),因此如果列dtype使用astype(str)进行更改,则其值也可以替换为整数。

相关问题