如何使用np.genfromtxt并填写缺少的列?

时间:2017-09-29 04:49:29

标签: python numpy

我正在尝试使用np.genfromtxt将类似这样的数据加载到矩阵中:

0.79  0.10  0.91   -0.17 0.10  0.33  -0.90 0.10  -0.19 -0.00 0.10  -0.99 -0.06 0.10  -0.42 -0.66 0.10  -0.79 0.21  0.10  0.93  0.79  0.10  0.91  -0.72 0.10  0.25  0.64  0.10  -0.27 -0.36 0.10  -0.66 -0.52 0.10  0.92  -0.39 0.10  0.43  0.63  0.10  0.25  -0.58 0.10  -0.03 0.59  0.10  0.02  -0.69 0.10  0.79  0.30  0.10  0.09  0.70  0.10  0.67  -0.04 0.10  -0.65 -0.07 0.10  0.70  -0.06 0.10  0.08  7  566 112 32 163 615 424 543 424 422 490 47 499 595 94 515 163 535 
 0.79  0.10  0.91   -0.17 0.10  0.33  -0.90 0.10  -0.19 -0.00 0.10  -0.99 -0.06 0.10  -0.42 -0.66 0.10  -0.79 0.21  0.10  0.93  0.79  0.10  0.91  -0.72 0.10  0.25  0.64  0.10  -0.27 -0.36 0.10  -0.66 -0.52 0.10  0.92  -0.39 0.10  0.43  0.63  0.10  0.25  -0.58 0.10  -0.03 0.59  0.10  0.02  -0.69 0.10  0.79  0.30  0.10  0.09  0.70  0.10  0.67  -0.04 0.10  -0.65 -0.07 0.10  0.70  -0.06 0.10  0.08  263 112 32 30 163 366 543 457 424 422 556 55 355 485 112 515 163 509 112 535 
 0.79  0.10  0.91   -0.17 0.10  0.33  -0.90 0.10  -0.19 -0.00 0.10  -0.99 -0.06 0.10  -0.42 -0.66 0.10  -0.79 0.21  0.10  0.93  0.79  0.10  0.91  -0.72 0.10  0.25  0.64  0.10  -0.27 -0.36 0.10  -0.66 -0.52 0.10  0.92  -0.39 0.10  0.43  0.63  0.10  0.25  -0.58 0.10  -0.03 0.59  0.10  0.02  -0.69 0.10  0.79  0.30  0.10  0.09  0.70  0.10  0.67  -0.04 0.10  -0.65 -0.07 0.10  0.70  -0.06 0.10  0.08  311 112 32 543 457 77 639 355 412 422 509 112 535 163 77 125 30 412 422 556 55 355 485 112 515 

假设我想将数据导入大小为(4,5)的矩阵。如果并非所有行都有5列,那么当它导入矩阵时,它应该用#34;"替换那些没有5行的列。例如,如果数据更简单,它将如下所示:

1,2,3,4,5
6,7,8,9,10
11,12,13,14,15
16,"","","",""

因此,我希望导入的列数与最大行列数相匹配,如果一行没有那么多列,则会用"&#34填充它;。我正在读取名为" data.txt"。

的文件

这是我到目前为止所尝试的:

trainData = np.genfromtxt('data.txt', usecols = range(0, 5), invalid_raise=False, missing_values = "", filling_values="")

但是,它会出错:

Line #4 (got 1 columns instead of 5)

我该如何解决这个问题?

谢谢!

4 个答案:

答案 0 :(得分:1)

Pandas拥有更强大的读者,您可以使用DataFrame方法来处理缺失值。

您必须先确定要使用的列数:

columns = max(len(l.split()) for l in open('data.txt'))

要阅读文件:

import pandas
df = pandas.read_table('data.txt', 
                       delim_whitespace=True, 
                       header=None, 
                       usecols=range(columns), 
                       engine='python')

要转换为numpy数组:

import numpy
a = numpy.array(df)

这将在空白位置填写NaN。您可以使用.fillna()获取空白的其他值。

filled = numpy.array(df.fillna(999))

答案 1 :(得分:0)

您需要将filling_values参数修改为np.nan(其被认为是float类型,因此您不会遇到字符串转换问题)并将分隔符指定为逗号,因为默认情况下genfromtxt只需要空格作为分隔符:

trainData = np.genfromtxt('data.txt', usecols = range(0, 5), invalid_raise=False, missing_values = "", filling_values=np.nan, delimiter=',')

答案 2 :(得分:0)

我设法找到了解决方案。

df = pandas.DataFrame([line.strip().split() for line in open('data.txt', 'r')])
data = np.array(df)

答案 3 :(得分:0)

使用3个大行的copy-n-paste,这个pandas阅读器可以工作:

In [149]: pd.read_csv(BytesIO(txt), delim_whitespace=True,header=None,error_bad_
     ...: lines=False,names=list(range(91)))
Out[149]: 
     0    1     2     3    4     5    6    7     8    9   ...     81   82  \
0  0.79  0.1  0.91 -0.17  0.1  0.33 -0.9  0.1 -0.19 -0.0  ...    515  163   
1  0.79  0.1  0.91 -0.17  0.1  0.33 -0.9  0.1 -0.19 -0.0  ...    515  163   
2  0.79  0.1  0.91 -0.17  0.1  0.33 -0.9  0.1 -0.19 -0.0  ...    125   30   

    83     84     85    86     87     88     89     90  
0  535    NaN    NaN   NaN    NaN    NaN    NaN    NaN  
1  509  112.0  535.0   NaN    NaN    NaN    NaN    NaN  
2  412  422.0  556.0  55.0  355.0  485.0  112.0  515.0  

_.values获取数组。

关键是指定一个足够大的names列表。 Pandas可以填充不完整的行,而genfromtxt需要明确的分隔符。