2013-05-18 12 views
43

Ho una serie di liste che contengono entrambe le stringhe e galleggiano i numeri, come ad esempio:Come usare python numpy.savetxt per scrivere stringhe e numeri mobili in un file ASCII?

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

voglio impilare questi due liste insieme e scrivere in un file di testo in forma di colonne; quindi, voglio usare numpy.savetxt (se possibile) per fare questo.

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

Quando faccio questo, ottengo il seguente errore:

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

Il file di output ideale sarebbe simile:

NAME_1 0.5 
NAME_2 0.2 
NAME_3 0.3 

Come posso scrivere entrambe le stringhe e galleggiare numeri per un file di testo, possibilmente evitando di usare csv (voglio renderlo leggibile per altre persone)? C'è un altro modo per farlo invece di usare numpy.savetxt?

risposta

72

è necessario specificare il formato (fmt) di voi dati in savetxt, in questo caso come una stringa (%s):

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

Il formato predefinito è un galleggiante, che è la ragione per cui si aspettava un float invece di una stringa e spiega il messaggio di errore.

+0

E cosa succede se voglio formattare i numeri? Come posso dare un po 'di formato ai numeri solo? – skytux

+4

Puoi dare diversi formati a colonne diverse, come 'fmt ="% f% i "'. Ma se vuoi combinarlo con le stringhe come nell'esempio sopra, avrai bisogno di un array strutturato (vedi [qui] (http://numpy-discussion.10968.n7.nabble.com/using-numpy-savetxt-to -save-colonne-di-numerico-valori-e-colonne-di-text-valori-td12304.html # nessuno)). In questo esempio, l'int viene convertito in una stringa e quindi la formattazione come int non è più possibile. – joris

21

La risposta attualmente accettata in realtà non affronta la domanda, che chiede come salvare elenchi che contengono sia stringhe che numeri mobili. Per completezza fornisco un esempio pienamente funzionante, che si basa, con alcune modifiche, sul link fornito nel commento @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") 

Aggiornamento: Questo esempio funziona correttamente anche in Python 3 utilizzando la stringa di Unicode dtype'U6', durante la creazione del abstructured array, al posto della stringa di 'S6' di byte. L'ultimo dtype funzionava in Python 2.7, ma scriveva stringhe come b'NAME_1' in Python 3.

+2

E se avessi una matrice float bidimensionale e volessi stampare ogni nome con il suo array corrispondente? L'unico modo sarebbe aggiungere tutte le righe manualmente o c'è un modo più semplice per farlo? Uscita prevista: NAME_1 0,1 0,2 0,3 – plethora