【问题标题】:Filling missing values using numpy.genfromtxt使用 numpy.genfromtxt 填充缺失值
【发布时间】:2013-06-22 20:07:13
【问题描述】:

尽管前面的问题给出了建议:

-9999 as missing value with numpy.genfromtxt()

Using genfromtxt to import csv data with missing values in numpy

我仍然无法处理以缺失值结尾的文本文件,

a.txt:

1 2 3
4 5 6
7 8

我尝试了missing_valuesfilling_values 的多种选项排列,但无法正常工作:

import numpy as np

sol = np.genfromtxt("a.txt", 
                    dtype=float,
                    invalid_raise=False, 
                    missing_values=None,
                    usemask=True,
                    filling_values=0.0)
print sol

我想得到的是:

[[1.0 2.0 3.0]
 [4.0 5.0 6.0]
 [7.0 8.0 0.0]]

但我得到了:

/usr/local/lib/python2.7/dist-packages/numpy/lib/npyio.py:1641: ConversionWarning: Some errors were detected !
    Line #3 (got 2 columns instead of 3)
  warnings.warn(errmsg, ConversionWarning)
[[1.0 2.0 3.0]
 [4.0 5.0 6.0]]

【问题讨论】:

  • 是否可以更改分隔符?
  • @Ophion 不,假定文本文件已按原样固定。我当然可以使用带有几个str.split 的普通python 加载文件,但问题是如何对numpy.genfromtxt 执行相同操作。
  • 您对使用 pandas 的解决方案感兴趣吗? (这很简单)。
  • Numpy 的 IOtools 使用 line.split(delimiter)。除非列是固定数量的字符,否则我不确定是否有解决方法。如前所述,py pandas 真的很棒——一旦我跳了起来,我的生活就变得简单多了。
  • 来自文档docs,“当使用空格作为分隔符时,或者当没有给出分隔符作为输入时,两个字段之间不应有任何缺失数据。”你根本无法做你想做的事。

标签: python parsing numpy genfromtxt


【解决方案1】:

使用pandas

import pandas as pd

df = pd.read_table('data', sep='\s+', header=None)
df.fillna(0, inplace=True)
print(df)
#    0  1  2
# 0  1  2  3
# 1  4  5  6
# 2  7  8  0

pandas.read_tableNaNs 替换缺失的数据。您可以使用 df.fillna 将这些 NaNs 替换为其他值。

dfpandas.DataFrame。您可以使用df.values 访问底层 NumPy 数组:

print(df.values)
# [[ 1.  2.  3.]
#  [ 4.  5.  6.]
#  [ 7.  8.  0.]]

【讨论】:

  • 您可以在pd.read_table 中添加dtype=float 关键字以获得他想要的数据类型...+1 tho
  • 我很欣赏这个答案,并将研究熊猫的未来。该问题专门针对genformtxt 和扩展numpy,因此我接受了基于此的另一个答案。
【解决方案2】:

问题是 numpy 不喜欢参差不齐的数组。由于文件最后一行的第三个位置没有字符,所以 genfromtxt 甚至都不知道它是要解析的东西,更不用说如何处理它了。如果缺失值有一个填充符(任何填充符),例如:

1 2 3
4 5 6
7 8 ''

那么你就可以:

sol = np.genfromtxt("a.txt",
                dtype=float,
                invalid_raise=False,
                missing_values='',
                usemask=False,
                filling_values=0.0)

和: 溶胶

array([[  1.,   2.,   3.],
       [  4.,   5.,   6.],
       [  7.,   8.,  nan]])

不幸的是,如果无法选择统一文件的列,您可能会被逐行解析所困。

另一种可能性是如果所有“短”行都在末尾...在这种情况下,您可以利用 'usecols' 标志来解析所有统一的列,然后使用 skip_footer 标志来解析对剩余的列执行相同的操作,同时跳过不可用的列:

sol = np.genfromtxt("a.txt",
                dtype=float,
                invalid_raise=False,
                usemask=False,
                filling_values=0.0,
                usecols=(0,1))
sol
array([[ 1.,  2.],
   [ 4.,  5.],
   [ 7.,  8.]])

sol2 = np.genfromtxt("a.txt",
                dtype=float,
                invalid_raise=False,
                usemask=False,
                filling_values=0.0,
                usecols=(2,),
                skip_footer=1)
sol2
array([ 3.,  6.])

然后从那里合并数组并添加填充值:

sol2=np.append(sol2, 0.0)
sol2=sol2.reshape(3,1)
sol=np.hstack([sol,sol2])
sol
array([[ 1.,  2.,  3.],
   [ 4.,  5.,  6.],
   [ 7.,  8.,  0.]])

【讨论】:

  • 谢谢,我没有考虑usecols 的解决方案,我一般应该提前知道哪一列会丢失,坏行总是在最后。
【解决方案3】:

根据我的经验,最好的方法是手动解析,这个功能对我有用,它可能很慢但通常足够快。

def manual_parsing(filename,delim,dtype):
    out = list()
    lengths = list()
    with open(filename,'r') as ins:
        for line in ins:
            l = line.split(delim)
            out.append(l)
            lengths.append(len(l))
    lim = np.max(lengths)
    for l in out:
        while len(l)<lim:
            l.append("nan")
    return np.array(out,dtype=dtype)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-29
    • 1970-01-01
    相关资源
    最近更新 更多