Ajouter par programmation des noms de colonne de numpy ndarray

j'essaie d'ajouter des noms de colonnes à un numpy ndarray, puis de sélectionner des colonnes par leurs noms. Mais ça ne fonctionne pas. Je ne peux pas dire si le problème survient lorsque j'ajoute les noms, ou plus tard, quand j'essaie de les appeler.

Voici mon code.

data = np.genfromtxt(csv_file, delimiter=',', dtype=np.float, skip_header=1)

#Add headers
csv_names = [ s.strip('"') for s in file(csv_file,'r').readline().strip().split(',')]
data = data.astype(np.dtype( [(n, 'float64') for n in csv_names] ))

les diagnostics basés sur les dimensions correspondent à ce que j'attends:

print len(csv_names)
>> 108
print data.shape
>> (1652, 108)

"les données d'impression.dtype.les noms" renvoie également la sortie attendue.

mais quand je commence à appeler des colonnes par leurs noms de champ, des choses bizarres arriver. La "colonne" est encore un tableau avec 108 colonnes...

print data["EDUC"].shape
>> (1652, 108)

... et il semble contenir plus de valeurs manquantes qu'il y a de lignes dans le jeu de données.

print np.sum(np.isnan(data["EDUC"]))
>> 27976

une idée de ce qui ne va pas ici? Ajouter des en-têtes devrait être une opération insignifiante, mais j'ai combattu ce bug pendant des heures. À l'aide!

12
demandé sur Saullo G. P. Castro 2012-05-24 21:26:49

2 réponses

le problème est que vous pensez en termes de tableaux de type tableur, alors que NumPy utilise des concepts différents.

voici ce que vous devez savoir à propos de NumPy:

  1. les tableaux NumPy ne contiennent que des éléments d'un type.
  2. si vous avez besoin de tableur-comme "colonnes", ce type doit être certains type "tuple-like". De tels tableaux sont appelés tableaux structurés, parce que leurs éléments sont des structures (i.e. tuple.)

dans votre cas, NumPy prendrait donc votre tableau régulier en 2 dimensions et produirait un -tableau dimensionnel dont le type est un tuple de 108 éléments (le tableau de tableur auquel vous pensez est en 2 dimensions).

ces choix ont probablement été faits pour des raisons d'efficacité: tous les éléments d'un tableau ont le même type et donc la même taille: ils sont accessibles, à un bas niveau, très simplement et rapidement.

maintenant, comme l'a montré user545424, il y a une réponse toute simple à ce que vous voulez faire (genfromtxt() accepte un names argument avec les noms de colonne).

si vous voulez convertir votre tableau d'un ndarray normal à un tableau structuré, vous pouvez faire:

data.view(dtype=[(n, 'float64') for n in csv_names]).reshape(len(data))

(vous étiez à proximité:astype() au lieu de view()).

vous pouvez également vérifier les réponses à un certain nombre de questions Stackoverflow, y compris conversion D'un tableau 2D de numpy pour un tableau structuré et comment convertir un tableau numpy régulier en tableau d'enregistrement?.

14
répondu Eric Lebigot 2017-05-23 12:08:48

Malheureusement, je ne sais pas ce qui se passe lorsque vous essayez d'ajouter les noms de champ, mais je sais que vous pouvez construire le tableau que vous voulez directement à partir du fichier via

data = np.genfromtxt(csv_file, delimiter=',', names=True)

EDIT:

Il semble que l'ajout de noms de champ ne fonctionne que lorsque l'entrée est une liste de tuples:

data = np.array(map(tuple,data), [(n, 'float64') for n in csv_names])
3
répondu user545424 2012-05-24 18:21:29