использование pandas read_csv с отсутствующими данными

Я пытаюсь прочитать файл csv, где в некоторых строках могут отсутствовать фрагменты данных.

По-видимому, это вызывает проблему с функцией pandas read_csv, когда вы указываете dtype. Проблема заключается в том, что для преобразования из str в значение, заданное dtype, pandas просто пытается выполнить его напрямую. Поэтому, если что-то не хватает, все ломается.

Далее следует MWE (этот MWE использует StringIO вместо истинного файла, однако проблема также возникает при использовании реального файла)

import pandas as pd import numpy as np import io datfile = io.StringIO("12 23 43| | 37| 12.23| 71.3\n12 23 55|X| | | 72.3") names = ['id', 'flag', 'number', 'data', 'data2'] dtypes = [np.str, np.str, np.int, np.float, np.float] dform = {name: dtypes[ind] for ind, name in enumerate(names)} colconverters = {0: lambda s: s.strip(), 1: lambda s: s.strip()} df = pd.read_table(datfile, sep='|', dtype=dform, converters=colconverters, header=None, index_col=0, names=names, na_values=' ') 

Ошибка, которую я получаю, когда я запускаю это

 Traceback (most recent call last): File "pandas/parser.pyx", line 1084, in pandas.parser.TextReader._convert_tokens (pandas/parser.c:12580) TypeError: Cannot cast array from dtype('O') to dtype('int64') according to the rule 'safe' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/Users/aliounis/Repos/stellarpy/source/mwe.py", line 15, in <module> index_col=0, names=names, na_values=' ') File "/usr/local/lib/python3.5/site-packages/pandas/io/parsers.py", line 562, in parser_f return _read(filepath_or_buffer, kwds) File "/usr/local/lib/python3.5/site-packages/pandas/io/parsers.py", line 325, in _read return parser.read() File "/usr/local/lib/python3.5/site-packages/pandas/io/parsers.py", line 815, in read ret = self._engine.read(nrows) File "/usr/local/lib/python3.5/site-packages/pandas/io/parsers.py", line 1314, in read data = self._reader.read(nrows) File "pandas/parser.pyx", line 805, in pandas.parser.TextReader.read (pandas/parser.c:8748) File "pandas/parser.pyx", line 827, in pandas.parser.TextReader._read_low_memory (pandas/parser.c:9003) File "pandas/parser.pyx", line 904, in pandas.parser.TextReader._read_rows (pandas/parser.c:10022) File "pandas/parser.pyx", line 1011, in pandas.parser.TextReader._convert_column_data (pandas/parser.c:11397) File "pandas/parser.pyx", line 1090, in pandas.parser.TextReader._convert_tokens (pandas/parser.c:12656) ValueError: invalid literal for int() with base 10: ' ' 

Я могу это исправить. Я просмотрел документацию, но не видел ничего похожего на то, что оно напрямую обратится к этому решению. Это просто ошибка, о которой нужно сообщить панде?

2 Solutions collect form web for “использование pandas read_csv с отсутствующими данными”

Попробуй это:

 import pandas as pd import numpy as np import io datfile = io.StringIO(u"12 23 43| | 37| 12.23| 71.3\n12 23 55|X| | | 72.3") names = ['id', 'flag', 'number', 'data', 'data2'] dtypes = [np.str, np.str, np.str, np.float, np.float] dform = {name: dtypes[ind] for ind, name in enumerate(names)} colconverters = {0: lambda s: s.strip(), 1: lambda s: s.strip()} df = pd.read_table(datfile, sep='|', dtype=dform, converters=colconverters, header=None, na_values=' ') df.columns = names 

Изменить: конвертировать dtypes post import.

 df["number"] = df["data"].astype('int') df["data"] = df["data"].astype('float') 

Ваши данные смешиваются с пробелами как str и номерами.

 <class 'pandas.core.frame.DataFrame'> RangeIndex: 2 entries, 0 to 1 Data columns (total 5 columns): id 2 non-null object flag 2 non-null object number 2 non-null object data 2 non-null object data2 2 non-null float64 dtypes: float64(1), object(4) memory usage: 152.0+ bytes 

Если вы посмотрите на data то это np.float но преобразуется в объект, а data2np.float до пустого, тогда он также превратится в объект.

Итак, как отметил Мерлин, основная проблема заключается в том, что nan не может быть ints, и, вероятно, поэтому панды действуют таким образом, чтобы начать. У меня, к сожалению, не было выбора, поэтому мне пришлось внести некоторые изменения в исходный код pandas. Мне пришлось изменить строки 1087-1096 файла parser.pyx на

  na_count_old = na_count print(col_res) for ind, row in enumerate(col_res): k = kh_get_str(na_hashset, row.strip().encode()) if k != na_hashset.n_buckets: col_res[ind] = np.nan na_count += 1 else: col_res[ind] = np.array(col_res[ind]).astype(col_dtype).item(0) if na_count_old==na_count: # float -> int conversions can fail the above # even with no nans col_res_orig = col_res col_res = col_res.astype(col_dtype) if (col_res != col_res_orig).any(): raise ValueError("cannot safely convert passed user dtype of " "{col_dtype} for {col_res} dtyped data in " "column {column}".format(col_dtype=col_dtype, col_res=col_res_orig.dtype.name, column=i)) 

который, по существу, проходит через каждый элемент столбца, проверяет, содержится ли каждый элемент в списке na (обратите внимание, что мы должны разбить материал, чтобы многопользовательские пространства отображались как находящиеся в списке na). Если это то, то этот элемент задается как double np.nan . Если он не находится в списке na, он переводится в исходный dtype, указанный для этого столбца (это означает, что столбец будет иметь несколько типов dtypes).

Хотя это не идеальное решение (и, скорее всего, оно медленное), оно работает для моих нужд, и, возможно, кто-то другой, у кого есть аналогичная проблема, найдет его полезным.

  • Какой смысл индексирования .ix для серии pandas
  • Параллельная итерация python
  • rpy2 (версия 2.3.10) - импорт данных из пакета R в python
  • Планирование кадров данных Pandas
  • pandas: Вычисленный столбец на основе значений в одном столбце
  • Как сделать кумулятивный "все"
  • Стандартная ошибка, игнорирующая NaN в группах групп pandas
  • Pandas pivot_table на дату
  • Объединение строк двух данных в пандах
  • Панды с rpy2 и многопроцессорность
  • Подсчитайте, если: задание находится в определенном временном интервале
  •  
    Interesting Posts for Van-Lav
    Python - лучший язык программирования в мире.