Заборонити пандам інтерпретувати 'NA' як NaN у рядку


81

Метод pandas read_csv () інтерпретує 'NA' як nan (а не число) замість дійсного рядка.

У наведеному нижче простому випадку зауважте, що в рядку 1, стовпці 2 (кількість, що базується на нулі) виводиться „nan“ замість „NA“.

sample.tsv (розділена табуляцією)

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 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)

Додаткова інформація

Повторне записування файлу з лапками для даних у стовпці «ЛАНЦЮГ», а потім використання параметра quotechar quotechar='\''має той самий результат. І передача словника типів через параметр dtype dtype=dict(valid_cols)не змінює результат.

Стара відповідь щодо запобігання автоматичному виведенню пандами типу read_csv пропонує спочатку використовувати масив записів numpy для синтаксичного аналізу файлу, але з огляду на можливість тепер вказувати типи d стовпців, це не повинно бути необхідним.

Зверніть увагу, що itertuples () використовується для збереження dtypes, як описано в документації iterrows: "Щоб зберегти dtypes під час ітерації по рядках, краще використовувати itertuples (), який повертає кортежі значень і який, як правило, швидший, ніж iterrows."

Приклад був протестований на Python 2 і 3 з версіями панд 0.16.2, 0.17.0 та 0.17.1.


Чи є спосіб захопити дійсний рядок 'NA' замість того, щоб перетворити його на nan?


Справа не в тому, що він розглядає його як число, а навпаки, вказує на те, що у вас відсутні дані . Я не знаю, у чому полягає виправлення у вашому випадку, але просто подумав, що ви повинні це знати.
Джефф Меркадо,

@JeffMercado Якщо ви спробуєте наведений нижче приклад Антона, але видалите keep_default_na=False, ви побачите, що NaN насправді є <class 'float'>.
бінарний субстрат

@binarysubstrate Можливо, ви можете трохи обрізати своє запитання (наприклад, лише зберегти "просту справу"), це зробить це питання більш цілеспрямованим та кориснішим для інших читачів (оскільки це дуже гарне питання!)
joris

@joris Гарна пропозиція. Я зробив редакцію, щоб спростити питання та зменшити довжину.
binarysubstrate

Відповіді:


73

Можна використовувати параметри keep_default_naі na_valuesвстановити всі значення NA ручних документами :

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-значень (станом на pandas1.0.0):

Значеннями, визнаними за замовчуванням, є ['-1. # IND', '1. # QNAN', '1. # IND', '-1. # QNAN', '# N / AN / A', '# N / A ',' N / A ',' n / a ',' NA ',' ',' #NA ',' NULL ',' null ',' NaN ',' -NaN ',' nan ',' - nan ',' '].


1
Дякуємо, що згадали, як адаптувати на-значення відповідно до вимог. Мені потрібно було лише вилучити зі списку Н / З та НС. Мені потрібно було залишити решту.
nitin3685

Дякую, ти
Ромен Норберг,

43

Для мене рішення прийшло з використанням параметра na_filter = False

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

11

Параметр налаштування 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

Довідково:

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.