2011-11-05 3 views
3

Existe-t-il une fonction dans numpy qui détermine si les chaînes doivent être des entiers ou des nombres à virgule flottante et les convertit automatiquement? Par exemple, j'ai souvent une collection d'enregistrements qui sont analysés à partir d'un fichier texte en utilisant une combinaison de str.strip() et str.split(). Puis-je obtenir quelque chose commedétection/conversion automatique des types de données?

List = [['1','a','.3'], 
     ['2','b','-.5']] 

qui est ensuite converti en utilisant numpy.rec.fromrecords:

In [1227]: numpy.rec.fromrecords(List) 
Out[1227]: 
rec.array([('1', 'a', '.3'), ('2', 'b', '-.5')], 
     dtype=[('f0', '|S1'), ('f1', '|S1'), ('f2', '|S3')]) 

En R, il y a une fonction appelée type.convert à laquelle vecteurs/colonnes de chaînes de caractères sont passés et il déterminera ce le type de la colonne doit être (c'est-à-dire s'il s'agit d'un mélange de chaînes et de nombres, il restera un vecteur de caractères). Excel le fait aussi (sur la base de ses 6 premiers éléments, si je me souviens bien) ...

Existe-t-il une telle fonction dans NumPy/Python? Je sais que je pourrais probablement écrire une fonction pour tester si chaque élément d'une colonne pourrait être converti en un entier, etc., mais y a-t-il quelque chose de intégré? Je sais que dans tous les exemples, la prescription est de spécifier explicitement les dtypes, mais je voudrais sauter cette étape. Merci.

Répondre

5

numpy.genfromtxt peut deviner dtypes si vous définissez dtype=None:

import numpy as np 
import io 

alist = [['1','a','.3'], 
     ['2','b','-.5']] 

f = io.BytesIO('\n'.join(' '.join(row) for row in alist)) 
arr = np.genfromtxt(f,dtype=None) 
print(arr) 
print(arr.dtype) 
# [(1, 'a', 0.3) (2, 'b', -0.5)] 
# [('f0', '<i4'), ('f1', '|S1'), ('f2', '<f8')] 

Notez qu'il serait préférable d'appliquer np.genfromtxt directement à votre fichier texte au lieu de créer la liste intermédiaire List (ou ce que j'appelais alist). Si vous devez faire un traitement du fichier avant de l'envoyer à np.genfromtxt, vous pouvez faire un file-like object wrapper autour du fichier qui peut effectuer le traitement et être passé à np.genfromtxt.

+1

C'est une solution très intéressante! Cela semble un peu indirect ... mais c'est peut-être encore la meilleure façon ... – hatmatrix

+0

En fait, le concept d'encapsulation d'objets est très utile, comme pour le truc 'io.BytesIO'. J'ai regardé le code source pour extraire la partie qui fait la conversion mais il semble que ce ne soit pas si simple car ce n'est pas son propre composant modulaire dans 'np.genfromtxt'. Cela semble mieux. – hatmatrix

Questions connexes