Предотвратите 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?
Ответы
Ответ 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
Ссылка: