Skip to main content
 首页 » 编程设计

python之从文本字段创建一个屏蔽数组

2025年05月04日9lovecherry

numpy documentation显示了使用 ma.masked 后验(在数组创建之后)屏蔽现有值的示例,或者从看似有效的数据类型列表创建屏蔽数组(如果 dtype=整数)。我正在尝试从文件中读取数据(并且需要一些文本操作),但在某些时候我将有一个列表(或元组)列表,其中包含我想从中创建数字(浮点)数组的字符串。

数据示例可能是 textdata='1\t2\t3\n4\t\t6'(清理后的典型纯文本格式)。

我遇到的一个问题是缺失值可能被编码为“”,当尝试使用 dtype 参数转换为 float 时,它会告诉我

ValueError: setting an array element with a sequence.  

所以我创建了这个函数

def makemaskedarray(X,missing='',fillvalue='-999.',dtype=float): 
    arr = lambda x: x==missing and fillvalue or x     
    mask = lambda x: x==missing and 1 or 0 
    triple = dict(zip(('data','mask','dtype'), 
                      zip(*[(map(arr,x),map(mask,x)) for x in X])+ 
                      [dtype])) 
    return ma.array(**triple) 

这似乎可以解决问题:

>>> makemaskedarray([('1','2','3'),('4','','6')]) 
masked_array(data = 
 [[1.0 2.0 3.0] 
 [4.0 -- 6.0]], 
             mask = 
 [[False False False] 
 [False  True False]], 
       fill_value = 1e+20) 

是这样吗?或者有一个内置的功能?

请您参考如下方法:

你这样做的方式很好。 (虽然你绝对可以通过避免构建临时的“triple”字典来让它更具可读性,只是为了稍后扩展它,i.m.o.)

内置方式是使用numpy.genfromtxt .根据您需要对文本文件进行的预处理量,它可能会或可能不会执行您需要的操作。但是,作为一个基本示例:(使用 StringIO 来模拟文件...)

from StringIO import StringIO 
import numpy as np 
 
txt_data = """ 
1\t2\t3 
4\t\t6 
7t\8t\9""" 
 
infile = StringIO(txt_data) 
data = np.genfromtxt(infile, usemask=True, delimiter='\t') 

产生:

masked_array(data = 
 [[1.0 2.0 3.0] 
 [4.0 -- 6.0] 
 [7.0 8.0 9.0]], 
             mask = 
 [[False False False] 
 [False  True False] 
 [False False False]], 
       fill_value = 1e+20) 

请注意:如果您确实使用制表符作为分隔符并使用空字符串作为缺失值标记,则会遇到行首缺失值的问题。 (genfromtxt 实质上调用了 line.strip().split(delimiter))。如果可以的话,最好使用 "xxx" 之类的东西作为缺失值的标记。