阻止熊猫默默转换超过dtype限制的数字

时间:2018-12-19 08:11:00

标签: python pandas numpy

我正在尝试将csv文件读取到pandas.DataFrame中。在阅读时,我确实指定了dtype。有时,数据输入不符合dtype要求,而熊猫会默默地(!)转换输入。我希望该操作引发异常。

这是我的代码:

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限制时(或可能使NumPy像在my_arr = pd.np.array([1, -1], dtype=pd.np.uint8)时一样做),如何使熊猫引发异常?

1 个答案:

答案 0 :(得分:2)

这似乎pandas太有用了,您可以定义自己的func并将其传递给converters来检查值是否在给定dtype的数值范围内:

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要验证,则需要手动构建转换器字典