использование 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).

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

  • DataFrame.apply в python pandas изменяет как исходные, так и повторяющиеся DataFrames
  • Данные и скорость передачи данных Pandas
  • Заполнить недостающие значения строк в кадре данных pandas
  • Столбцы Pandas для записи в csv
  • Не удается установить Pandas с OpenShift
  • Как ускорить ближайший поиск в Pandas (возможно, путем векторизации кода)
  • Как сформировать столбец кортежа из двух столбцов в Pandas
  • Чтение больших текстовых файлов с помощью Pandas
  • Python - лучший язык программирования в мире.