Не позволяйте пандам молча преобразовывать числа, превышающие пределы dtype - PullRequest
0 голосов
/ 19 декабря 2018

Я пытаюсь прочитать 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 голосов
/ 19 декабря 2018

Кажется, что pandas слишком полезно, вы можете определить свой собственный функционал и передать его в 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 s для проверки, тогда вам нужно будет вручную создать ваш конвертер dict

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...