web-dev-qa-db-fra.com

Comment utiliser python numpy.savetxt pour écrire des chaînes et un nombre flottant dans un fichier ASCII?

J'ai un ensemble de listes contenant à la fois des chaînes et des nombres flottants, tels que:

import numpy as num

NAMES  = num.array(['NAME_1', 'NAME_2', 'NAME_3'])
FLOATS = num.array([ 0.5    , 0.2     , 0.3     ])

DAT =  num.column_stack((NAMES, FLOATS))

Je veux empiler ces deux listes et les écrire dans un fichier texte sous forme de colonnes; par conséquent, je veux utiliser numpy.savetxt (si possible) pour le faire.

num.savetxt('test.txt', DAT, delimiter=" ") 

Lorsque je fais cela, j'obtiens l'erreur suivante:

>>> num.savetxt('test.txt', DAT, delimiter=" ") 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Python/2.7/site-packages/numpy-1.8.0.dev_9597b1f_20120920-py2.7-macosx-10.8-x86_64.Egg/numpy/lib/npyio.py", line 1047, in savetxt
    fh.write(asbytes(format % Tuple(row) + newline))
TypeError: float argument required, not numpy.string_

Le fichier de sortie idéal ressemblerait à ceci:

NAME_1    0.5
NAME_2    0.2
NAME_3    0.3

Comment puis-je écrire les deux chaînes et les nombres flottants dans un fichier texte, en évitant éventuellement d’utiliser csv (que je souhaite rendre lisible par d’autres personnes)? Y a-t-il une autre façon de faire au lieu d'utiliser numpy.savetxt?

60
Victor

Vous devez spécifier le format (fmt) de vos données dans savetxt, dans ce cas sous forme de chaîne (%s):

num.savetxt('test.txt', DAT, delimiter=" ", fmt="%s") 

Le format par défaut est un float, c’est la raison pour laquelle il s’attendait à un float au lieu d’une chaîne et explique le message d’erreur.

99
joris

La réponse actuellement acceptée ne répond pas réellement à la question, qui demande comment enregistrer des listes contenant à la fois des chaînes et des nombres flottants. Par souci d'exhaustivité, je fournis un exemple pleinement fonctionnel, qui repose, avec quelques modifications, sur le lien indiqué dans le commentaire @joris.

import numpy as np

names  = np.array(['NAME_1', 'NAME_2', 'NAME_3'])
floats = np.array([ 0.1234 ,  0.5678 ,  0.9123 ])

ab = np.zeros(names.size, dtype=[('var1', 'U6'), ('var2', float)])
ab['var1'] = names
ab['var2'] = floats

np.savetxt('test.txt', ab, fmt="%10s %10.3f")

Mise à jour: Cet exemple fonctionne également correctement dans Python 3 en utilisant le 'U6' Chaîne Unicode dtype , lors de la création du abtableau structuré , à la place du 'S6' chaîne d'octets. Ce dernier type fonctionnerait avec Python 2.7, mais écrirait des chaînes comme b'NAME_1' in Python 3.

31
divenex