我有一个看起来像这样的json文件:
[{"A": 0, "B": "x"}, {"A": 1, "B": "y", "C": 0}, {"A": 2, "B": "z", "C": 1}]
由于“ C”列包含NaN值(第一行),因此熊猫自动推断其dtype为“ float64”:
>>> pd.read_json(path).C.dtype
dtype('float64')
但是,我希望“ C”列的dtype为“ Int32”。pd.read_json(path, dtype={"C": "Int32"})
不起作用:
>>> pd.read_json(path, dtype={"C": "Int32"}).C.dtype
dtype('float64')
相反,pd.read_json(path).astype({"C": "Int32"})
它可以工作:
>>> pd.read_json(path).astype({"C": "Int32"}).C.dtype
Int32Dtype()
为什么会这样?如何仅通过使用pd.read_json
函数来设置正确的dtype ?
原因是在此代码部分中:
dtype = (
self.dtype.get(name) if isinstance(self.dtype, dict) else self.dtype
)
if dtype is not None:
try:
dtype = np.dtype(dtype)
return data.astype(dtype), True
except (TypeError, ValueError):
return data, False
尝试将整个列(数组)转换为该类型时,它将转换'Int32'
为numpy.int32
,从而导致值错误(无法将非有限值(NA或inf)转换为整数)。因此,原始(未转换的)数据将在异常块中返回。
我猜这是熊猫中的某种错误,至少该行为没有正确记录。
astype
另一方面,它的工作方式有所不同:它在系列中逐个应用'astype'
),因此可以创建混合类型的列。
有趣的是,当直接指定扩展类型 pd.Int32Dtype()
(而不是其字符串别名'Int32'
)时,乍一看就可以得到所需的结果,但是如果您查看这些类型,它们仍然是浮动的:
df = pd.read_json(json, dtype={"C": pd.Int32Dtype})
print(df)
# A B C
#0 0 x NaN
#1 1 y 0
#2 2 z 1
print(df.C.map(type))
#0 <class 'float'>
#1 <class 'float'>
#2 <class 'float'>
#Name: C, dtype: object
为了比较:
print(df.C.astype('Int32').map(type))
#0 <class 'pandas._libs.missing.NAType'>
#1 <class 'int'>
#2 <class 'int'>
#Name: C, dtype: object
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句