防止熊猫将'NA'解释为字符串中的NaN


79

熊猫的read_csv()方法将'NA'解释为nan(不是数字),而不是有效的字符串。

在下面的简单情况下,请注意,第1行第2列(基于零的计数)的输出为'nan'而不是'NA'。

sample.tsv(制表符分隔)

PDB链SP_PRIMARY RES_BEG RES_END PDB_BEG PDB_EN​​D SP_BEG SP_END
5d8b N P60490 1146 1146 1146
5d8b NA P80377 1 126
1126 1126 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)不会更改结果。

阻止read_csv中的熊猫自动推断类型的旧答案建议首先使用numpy记录数组来解析文件,但是鉴于现在可以指定列dtypes,因此不必这样做。

请注意,按照iterrows文档中的描述,itertuples()用于保留dtype:“要在迭代行时保留dtype,最好使用itertuples()返回值的元组,并且通常在迭代时更快。”

该示例已在Python 2和3上使用pandas版本0.16.2、0.17.0和0.17.1进行了测试。


有没有办法捕获有效的字符串“ NA”,而不是将其转换为nan?


不是将其视为数字,而是表明您缺少数据。我不知道您的解决方案是什么,只是想您应该知道。
Jeff Mercado 2015年

@JeffMercado如果尝试以下Anton的示例,但是将其删除keep_default_na=False,则会看到NaN实际上是<class 'float'>
binarysubstrate 2015年

@binarysubstrate也许您可以考虑对问题进行一些调整(例如,仅保留“简单案例”),这将使问题更加集中并且对其他读者更有用(因为这是一个很好的问题!)
joris

@joris好建议。我进行了编辑以简化问题并缩短篇幅。
binarysubstrate

Answers:


72

您可以使用参数keep_default_nana_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值(自1.0.0起):pandas

NaN识别的默认值是['-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
感谢您提到如何根据需求定制na值。我只需要从列表中删除N / A和NA。我需要保留其余的。
nitin3685 '19

谢谢,您保存我的一天
Romain Norberg

42

对我来说,解决方案来自使用参数 na_filter = False

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

11

设置keep_default_na参数可以解决问题。

这是NA使用Pandas读取CSV文件时保持字符串值的示例。

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

参考:

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.