我正在尝试将 csv 文件读入 pandas.DataFrame。在阅读时我确实指定了 dtype。有时数据输入不满足数据类型要求,pandas 会默默地(!)转换输入。我希望该操作引发异常。
这是我的代码:
from io import StringIO
import pandas as pd
my_csv = StringIO('foo\n1\n-1')
my_df = pd.read_csv(my_csv, dtype=pd.np.uint8)
my_df
输出:
foo
0 1
1 255
-1
已转换为 255
,因为它不适合 np.uint8限制。
问题是:
1)为什么会悄无声息地过去?
2) 当输入不符合 dtype 限制时,如何让 pandas 引发异常(或者可能让 NumPy 引发异常,因为它在 my_arr = pd.np.array([1, - 1], dtype=pd.np.uint8)
)?
最佳答案
这似乎是 pandas
太有用了,您可以定义自己的函数并将其传递给 converters
以检查这些值是否在给定的数字限制内数据类型
:
In[28]:
import numpy as np
import io
typ = np.uint8
def foo1(x):
if np.iinfo('uint8').min > np.int(x) < np.iinfo('uint8').max :
raise ValueError('{0} outside numeric limits'.format(x))
return x
# df creation code from @coldspeed
df = pd.read_csv(io.StringIO('foo\n1\n-1'), converters={'foo':foo1})
df
加薪:
4 def foo1(x):
5 if np.iinfo('uint8').min > np.int(x) < np.iinfo('uint8').max :
----> 6 raise ValueError('{0} outside numeric limits'.format(x))
7 return x
8
ValueError: -1 outside numeric limits
通用解决方案
def foo1(x,dtype):
if np.dtype(dtype).kind == 'f'
if np.finfo(dtype).min > np.float64(x) < np.finfo(dtype).max :
elif np.iinfo(dtype).min > np.int(x) < np.iinfo(dtype).max :
raise ValueError('{0} outside numeric limits'.format(x))
return x
这样您就可以在所有列上调用它:
columns = pd.read_csv(...., nrows=1).columns
然后压缩列以制作字典并使用转换器:
col_converters = dict(zip(columns, foo1))
然后传递给read_csv
:
pd.read_csv(..., converters=col_converters)
虽然这期望您的数据是单个dtype
,但如果您有多个dtype
需要验证,那么您需要手动构建转换器字典
关于python - 阻止 pandas 默默地转换超出 dtype 限制的数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53846993/