我有一个json文件,看起来像这样。
[{"A": 0, "B": "x"}, {"A": 1, "B": "y", "C": 0}, {"A": 2, "B": "z", "C": 1}]
由于 "C "列包含一个NaN值(第一行),pandas自动推断它的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 = (
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)转换为整数)。由于这个原因,原始(未转换的)数据在异常块中被返回。我想这是pandas中的某个bug,至少这个行为没有被正确记录下来。
astype
而另一方面,pandas的工作方式不同:它的工作方式是 适用 '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
• Pandas:将 Float64 系列分配给 Int32 系列失败,类型错误
• 如何在 python/pandas 中保留 2 位小数而不四舍五入?
• Python:如何在 pandas 中读取 #0000000000 格式的 excel 列时保留前导零
• sklearn.impute.SimpleImputer:无法填写数据框列列表的最常见值
• 使用 python/pandas 计算子网中已使用/免费的 ip 地址
• 如果文件中有类似目录结构的列表,如何使用 pandas 从 blob 读取文件?
• 使用 python pandas 绘制特定列中数据的饼图
• Python pandas groupby:如何使用不同列中的变量创建一个新列
• 使用正则表达式从 pandas 数据框中的列中创建对字典
• Pandas Lookup 将被弃用 - 优雅高效的替代方案
• 使用ModuleDict,我有。输入类型(torch.cuda.FloatTensor)和权重类型(torch.FloatTensor)应该是一样的。