2014-12-16 16 views
7

Więc mam to, co uważam za bardzo głupi problem.Próba usunięcia b '' z mojej tablicy Numpy

utworzyć tablicę z pliku:

A1=np.loadtxt(file, dtype='a100') 

Chcę napisać tej tablicy po to się robi przetwarzania do innego pliku:

np.savetxt("Test.txt", A1, fmt=%s, delimiter=',') 

Dlaczego jest wypisywanie b'string '? Myślę, że rozumiem, że napisałem to jako bajt, ale dla mojego życia nie mogę wymyślić, jak napisać to bez b ''.

Wiem, że to prawdopodobnie coś niesamowicie łatwego.

+4

Masz bytearray. spójrz na http://stackoverflow.com/questions/606191/convert-bytes-to-a-python-string –

+0

Dzięki, popatrzę. Czy jest coś, co mogę zrobić z częścią formatowania savetext, aby to naprawić? – user2624599

Odpowiedz

2

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.

+0

Próbowałem twoją i to jest to, co dostałem jako błąd: 'Obiekt 'numpy.void' nie ma atrybutu 'decode'' – user2624599

+0

Co to jest typ d123? Jeśli 'x' jest' numpy.void', to zgaduję, że jest to element tablicy strukturalnej. '.decode' jest metodą' string'. – hpaulj