2013-04-25 15 views
6

Rozważmy tablicęwymuszona konwersja nienumerycznych tablic numpy z wymianą NAN

x = np.array(['1', '2', 'a'])

Materiały do ​​konwersji do tablicy pływak podnosi wyjątek

x.astype(np.float) 
ValueError: could not convert string to float: a 

robi numpy dostarczyć dowolny skuteczny sposób przymusić to do tablicy numerycznej, zastępując wartości nieliczbowe czymś takim jak NAN?

Alternatywnie jest skuteczne działanie numpy równoważne np.isnan, ale która umożliwia również testowanie elementów nie liczbowymi jak litery?

Odpowiedz

10

można przekonwertować tablicy ciągów do tablicy pływaków (z Nans) używając np.genfromtxt:

In [83]: np.set_printoptions(precision=3, suppress=True) 

In [84]: np.genfromtxt(np.array(['1','2','3.14','1e-3','b','nan','inf','-inf'])) 
Out[84]: array([ 1. , 2. , 3.14 , 0.001, nan, nan, inf, -inf]) 

W Python3 trzeba by przekształcić tablicę do bajtów pierwszy, na przykład jak poprzez np.astype():

In [18]: np.genfromtxt(np.array(['1','2','3.14','1e-3','b','nan','inf','-inf']).astype('bytes')) 
Out[18]: array([ 1. , 2. , 3.14 , 0.001, nan, nan, inf, -inf]) 

Oto sposób zidentyfikować "numeryczne" ciągi:

In [34]: x 
Out[34]: 
array(['1', '2', 'a'], 
     dtype='|S1') 

In [35]: x.astype('unicode') 
Out[35]: 
array([u'1', u'2', u'a'], 
     dtype='<U1') 

In [36]: np.char.isnumeric(x.astype('unicode')) 
Out[36]: array([ True, True, False], dtype=bool) 

Zauważ, że "numeryczny" oznacza Unicode, który zawiera tylko znaki cyfr - to znaczy, znaki, które mają wartość liczbową Unicode. Nie obejmuje ona , a nie włącznie z kropką dziesiętną. Tak więc u'1.3' nie jest uważany za "numeryczny".

+0

'np.genfromtxt' jest doskonały, dzięki! – ChrisB

+0

Odpowiedź ta może wymagać zmian dla python3 - Można by dostać 'TypeError: nie można przekonwertować obiekt„bajty”na str implicitly'. –

+0

@ cᴏʟᴅsᴘᴇᴇᴅ: Dzięki za heads-up. Naprawiono za pomocą 'astype ('bytes')'. – unutbu

4

Jeśli zdarzy ci się być za pomocą pandy jak dobrze można użyć metody pd.to_numeric():

In [1]: import numpy as np 

In [2]: import pandas as pd 

In [3]: x = np.array(['1', '2', 'a']) 

In [4]: pd.to_numeric(x, errors='coerce') 
Out[4]: array([ 1., 2., nan]) 
0

pd.to_numeric może być używany jak jest dla każdej tablicy 1D. Jednak dla dowolnej macierzy N-D (n> 1), to masz:

TypeError: arg must be a list, tuple, 1-d array, or Series 

Tak, trzeba zrobić trochę więcej. Na przykład:

In [340]: a 
Out[340]: 
array([['1', '1.1', 'a'], 
     ['ab', '1', '1.1']], 
     dtype='<U32') 

Teraz zmienią, konwersji, a następnie ponownie Reshape:

In [341]: pd.to_numeric(a.reshape(-1,), errors='coerce').reshape(a.shape) 
Out[341]: 
array([[ 1. , 1.1, nan], 
     [ nan, 1. , 1.1]])