A1
jest ładowany jako tablica bajtów. Python3 używał domyślnie łańcuchów unicode, więc zwykle poprzedzany jest znakami "b". To normalne z print
. Jestem trochę zaskoczony, że robi to również podczas zapisu pliku.
W każdym razie wydaje się to zrobić trick:
A2=np.array([x.decode() for x in A1])
np.savetxt("Test.txt", A2, fmt='%s', delimiter=',')
A2
będzie miał dtype jak dtype='<U100'
.
Moje testy tablica jest:
array([b'one.com', b'two.url', b'three.four'], dtype='|S10')
ładowane z prostego pliku tekstowego:
one.com
two.url
three.four
.decode
to metoda ciąg. [x.decode() for x in A1]
działa dla prostej tablicy 1d bytestrings. Jeśli A1
jest 2d, iteracja musi zostać wykonana na wszystkich elementach, a nie tylko na wierszach. A jeśli A1
jest tablicą strukturalną, należy ją zastosować do łańcuchów wewnątrz elementów.
Inną możliwością jest użycie konwertera podczas obciążenia, więc masz tablicę (Unicode) strun
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
lib, który zawiera loadtxt
ma kilka funkcji Converter asbytes
, asbytes_nested
, i asstr
. Więc converters
może również być: converters={0:np.lib.npyio.asstr}
.
genfromtxt
radzi sobie z tym bez converters
:
A1=np.genfromtxt('urls.txt', dtype='U')
# array(['one.com', 'two.url', 'three.four'], dtype='<U10')
Aby zrozumieć dlaczego savetxt
Zapisz unicode ciągi jak chcemy, ale dołącza b
dla bytestrings, musimy spojrzeć na jego kodzie.
np.savetxt
(działa na py3) jest w istocie:
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))
Patrząc na dwóch ciągów próbek (STR i 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'"
Zapis do 'wb' pliku usuwa że zewnętrzna warstwa b''
, pozostawiając wewnętrzną na bytestring. Wyjaśnia również, dlaczego łańcuchy ("zwykły" unicode py3) są zapisywane jako ciągi "latin1" do pliku.
Możesz napisać tablicę bytestrings bezpośrednio, bez savetxt
. Na przykład:
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
ciągi Unicode mogą być również zapisywane bezpośrednio, produkujących ten sam plik:
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')
Domyślne kodowanie dla takiego pliku jest encoding='UTF-8'
, taki sam jak stosowany z 'one.com'.encode()
. Efekt jest taki sam jak co savetxt
robi:
with open('test1.txt','wb') as f:
for x in A1:
f.write(x.encode()+b'\n')
np.char
ma .encode
i .decode
metody, które wydają się działać iteracyjnie na elementach tablicy.
Zatem
np.char.decode(A1) # convert |S10 to <U10, like [x.decode() for x in A1]
np.char.encode(A1) # convert <U10 to |S10
Działa z wielowymiarowych tablic
np.savetxt('testm.txt',np.char.decode(A_bytes[:,None][:,[0,0]]),
fmt='%s',delimiter=', ')
Z zorganizowanego tablicy np.char.decode
musi być stosowana indywidualnie dla każdego z pól char.
Masz bytearray. spójrz na http://stackoverflow.com/questions/606191/convert-bytes-to-a-python-string –
Dzięki, popatrzę. Czy jest coś, co mogę zrobić z częścią formatowania savetext, aby to naprawić? – user2624599