A1
viene caricato come una matrice di bytestrings. Python3 usava le stringhe unicode come default, quindi di solito le prepone con la 'b'. Questo è normale con print
. Sono un po 'sorpreso che lo faccia anche durante la scrittura del file.
In ogni caso, questo sembra fare il trucco:
A2=np.array([x.decode() for x in A1])
np.savetxt("Test.txt", A2, fmt='%s', delimiter=',')
A2
avrà un DTYPE come dtype='<U100'
.
La mia serie di test è:
array([b'one.com', b'two.url', b'three.four'], dtype='|S10')
caricato da un file di testo semplice:
one.com
two.url
three.four
.decode
è un metodo di stringa. [x.decode() for x in A1]
funziona per un semplice array 1d di bytestrings. Se A1
è 2d, l'iterazione deve essere eseguita su tutti gli elementi, non solo sulle righe. E se A1
è array strutturato, deve essere applicato alle stringhe all'interno degli elementi.
Un'altra possibilità è quella di utilizzare un convertitore durante il carico, in modo da ottenere una serie di (Unicode) stringhe
In [508]: A1=np.loadtxt('urls.txt', dtype='U',
converters={0:lambda x:x.decode()})
In [509]: A1
Out[509]:
array(['one.com', 'two.url', 'three.four'], dtype='<U10')
In [510]: np.savetxt('test0.txt',A1,fmt='%s')
In [511]: cat test0.txt
one.com
two.url
three.four
Il lib che contiene loadtxt
ha un paio di funzioni di conversione, asbytes
, asbytes_nested
, e asstr
. Quindi converters
potrebbe anche essere: converters={0:np.lib.npyio.asstr}
.
genfromtxt
gestisce questo senza converters
:
A1=np.genfromtxt('urls.txt', dtype='U')
# array(['one.com', 'two.url', 'three.four'], dtype='<U10')
Per comprendere il motivo per cui savetxt
Salva stringhe Unicode come vogliamo, ma aggiunge il b
per stringhe di byte, dobbiamo guardare al suo codice.
np.savetxt
(in esecuzione su PY3) è essenzialmente:
fh = open(fname, 'wb')
X = np.atleast_2d(X).T
# make a 'fmt' that matches the columns of X (with delimiters)
for row in X:
fh.write(asbytes(format % tuple(row) + newline))
Guardando due stringhe di esempio (str e bytestr):
In [617]: asbytes('%s'%tuple(['one.two']))
Out[617]: b'one.two'
In [618]: asbytes('%s'%tuple([b'one.two']))
Out[618]: b"b'one.two'"
scrittura su un file 'wb' rimuove quello strato esterno b''
, lasciando l'interno per il test. Spiega anche perché le stringhe ('plain' py3 unicode) sono scritte come stringhe 'latin1' nel file.
si potrebbe scrivere un array di stringhe di byte direttamente, senza savetxt
. Ad esempio:
A0 = array([b'one.com', b'two.url', b'three.four'], dtype='|S10')
with open('test0.txt','wb') as f:
for x in A0:
f.write(x+b'\n')
cat test0.txt
one.com
two.url
three.four
stringhe Unicode possono anche essere scritte direttamente, producendo lo stesso file:
A1 = array(['one.com', 'two.url', 'three.four'], dtype='<U10')
with open('test1.txt','w') as f:
for x in A1:
f.write(x+'\n')
La codifica predefinita per un file è encoding='UTF-8'
, lo stesso utilizzato con 'one.com'.encode()
. L'effetto è lo stesso di quello che fa savetxt
:
with open('test1.txt','wb') as f:
for x in A1:
f.write(x.encode()+b'\n')
np.char
ha .encode
e .decode
metodi, che sembrano operare iterativamente sugli elementi di un array.
Così
np.char.decode(A1) # convert |S10 to <U10, like [x.decode() for x in A1]
np.char.encode(A1) # convert <U10 to |S10
Questo funziona con array multidimensionali
np.savetxt('testm.txt',np.char.decode(A_bytes[:,None][:,[0,0]]),
fmt='%s',delimiter=', ')
Con una matrice strutturata, np.char.decode
deve essere applicati singolarmente per ciascuno dei campi char.
Hai un bytearray. guarda http://stackoverflow.com/questions/606191/convert-bytes-to-a-python-string –
Grazie, darò un'occhiata. C'è qualcosa che posso fare per la parte in formato di testo per ripararlo? – user2624599