Подтвердить что ты не робот

Предотвратите pandas от интерпретации "NA" как NaN в строке

Метод pandas read_csv() интерпретирует "NA" как nan (а не число) вместо допустимой строки.

В простом случае ниже обратите внимание, что вывод в строке 1, столбец 2 (подсчет с нулевой отметкой) является "нан" вместо "NA".

sample.tsv (с разделителями табуляции)

ЦАП PDB SP_PRIMARY RES_BEG RES_END PDB_BEG PDB_END SP_BEG SP_END
5d8b N P60490 1 146 1 146 1 146
5d8b NA P80377 1 126 1 126 1 126
5d8b O P60491 1 118 1 118 1 118

read_sample.py

import pandas as pd

df = pd.read_csv(
    'sample.tsv',
    sep='\t',
    encoding='utf-8',
)

for df_tuples in df.itertuples(index=True):
    print(df_tuples)

Выход

(0, u'5d8b ', u'N', u'P60490 ', 1, 146, 1, 146, 1, 146)
(1, u'5d8b ', nan, u'P80377', 1, 126, 1, 126, 1, 126)
(2, u'5d8b ', u'O', u'P60491 ', 1, 118, 1, 118, 1, 118)

Дополнительная информация

Повторная запись файла с кавычками для данных в столбце "CHAIN", а затем с использованием параметра quotechar quotechar='\'' имеет тот же результат. И передача словаря типов через параметр dtype dtype=dict(valid_cols) не изменяет результат.

Старый ответ Предотвратить pandas от автоматического вывода типа в read_csv предлагает сначала использовать массив записей numpy для синтаксического анализа файла, но с учетом возможности теперь указывать column dtypes, это не обязательно.

Обратите внимание, что itertuples() используется для сохранения dtypes, как описано в документации по iterrows: "Чтобы сохранить типы dtypes во время итерации по строкам, лучше использовать itertuples(), который возвращает кортежи значений и обычно быстрее iterrows".

Пример был протестирован на Python 2 и 3 с pandas версией 0.16.2, 0.17.0 и 0.17.1.


Есть ли способ захватить допустимую строку "NA" вместо ее преобразования в nan?

4b9b3361

Ответ 1

Вы можете использовать параметры keep_default_na и na_values для установки всех значений NA вручную docs:

import pandas as pd
from io import StringIO

data = """
PDB CHAIN SP_PRIMARY RES_BEG RES_END PDB_BEG PDB_END SP_BEG SP_END
5d8b N P60490 1 146 1 146 1 146
5d8b NA P80377 _ 126 1 126 1 126
5d8b O P60491 1 118 1 118 1 118
"""

df = pd.read_csv(StringIO(data), sep=' ', keep_default_na=False, na_values=['_'])

In [130]: df
Out[130]:
    PDB CHAIN SP_PRIMARY  RES_BEG  RES_END  PDB_BEG  PDB_END  SP_BEG  SP_END
0  5d8b     N     P60490        1      146        1      146       1     146
1  5d8b    NA     P80377      NaN      126        1      126       1     126
2  5d8b     O     P60491        1      118        1      118       1     118

In [144]: df.CHAIN.apply(type)
Out[144]:
0    <class 'str'>
1    <class 'str'>
2    <class 'str'>
Name: CHAIN, dtype: object

ИЗМЕНИТЬ

Все значения по умолчанию NA из na-values:

Значения, определенные по умолчанию NaN, равны ['-1.#IND', '1.#QNAN', '1.#IND', '-1.#QNAN', '#N/A','N/A', 'NA', '#NA', 'NULL', 'NaN', '-NaN', 'nan', '-nan']. Хотя строка длиной 0 строк не включена в список значений NaN по умолчанию, она по-прежнему рассматривается как недостающее значение.

Ответ 2

Для меня решение исходило из использования параметра na_filter = False

df = pd.read_csv(file_, header=0, dtype=object, na_filter = False)

Ответ 3

Установка параметра keep_default_na делает keep_default_na дело.

Вот пример сохранения NA качестве строкового значения при чтении файла CSV с использованием Pandas.

data.csv:

country_name,country_code
Mexico,MX
Namibia,NA

read_data.py:

import pandas as pd
data = pd.read_csv("data.csv", keep_default_na=False)
print(data.describe())
print(data)

Выход:

       country_name country_code
count             2            2
unique            2            2
top         Namibia           MX
freq              1            1

  country_name country_code
0       Mexico           MX
1      Namibia           NA

Ссылка: