2010-09-11 5 views
2

Le numpy documentation montre un exemple de masquage de valeurs existantes avec ma.masked à posteriori (après la création d'un tableau) ou la création d'un tableau masqué à partir d'une liste de types de données qui semblent valides (entier si dtype=int) . J'essaye de lire dans les données d'un fichier (et exige une certaine manipulation de texte) mais à un certain moment j'aurai une liste de listes (ou tuples) contenant des chaînes à partir de laquelle je veux faire un tableau numérique (float).Création d'un tableau masqué à partir des champs de texte

Un exemple de données peut être textdata='1\t2\t3\n4\t\t6' (format de texte plat standard après nettoyage).

Un problème que j'ai est que les valeurs manquantes peuvent être codées comme « », qui en essayant de convertir flotter en utilisant l'argument DTYPE, me dira

ValueError: setting an array element with a sequence. 

J'ai donc créé cette fonction

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) 

qui semble faire l'affaire:

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

Est-ce la façon de le faire? Ou il y a une fonction intégrée?

Répondre

1

La façon dont vous le faites est très bien. (Bien que vous puissiez certainement le rendre un peu plus lisible en évitant de construire le dict "triple" temporaire, juste pour le développer un peu plus tard, i.m.o.)

La méthode intégrée consiste à utiliser numpy.genfromtxt. Selon la quantité de pré-traitement que vous devez faire pour votre fichier texte, il peut ou ne peut pas faire ce dont vous avez besoin. Cependant, comme un exemple de base: (En utilisant StringIO pour simuler un fichier ...)

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

Ce qui donne:

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) 

Un mot d'avertissement: Si vous utilisez les onglets que votre delimiter et un chaîne vide en tant que marqueur de valeur manquante, vous aurez des problèmes avec des valeurs manquantes au début d'une ligne. (genfromtxt appelle essentiellement line.strip().split(delimiter)). Vous feriez mieux d'utiliser quelque chose comme "xxx" comme marqueur des valeurs manquantes, si vous le pouvez.

+0

Merci - pensé à genfromtxt mais a demandé trop de pré-traitement en premier, mais merci pour le conseil sur les valeurs manquantes en début de ligne! Et le tour de StringIO ... – hatmatrix

Questions connexes