2016-01-27 14 views
6

In Python, è possibile verificare se uno float contiene un valore intero utilizzando n.is_integer(), basato su questo QA: How to check if a float value is a whole number.Numpy: controlla se l'array float contiene numeri interi

Il numpy ha un'operazione simile che può essere applicata agli array? Qualcosa che avrebbe permesso la seguente:

>>> x = np.array([1.0 2.1 3.0 3.9]) 
>>> mask = np.is_integer(x) 
>>> mask 
array([True, False, True, False], dtype=bool) 

E 'possibile fare qualcosa di simile

>>> mask = (x == np.floor(x)) 

o

>>> mask = (x == np.round(x)) 

ma coinvolgono chiamare i metodi in più e la creazione di un gruppo di array temporanei che potrebbe essere potenzialmente evitato.

Il numpy ha una funzione vettorizzata che verifica la presenza di parti frazionarie di float in modo simile a quello di Python float.is_integer?

risposta

4

Da quello che posso dire, non esiste una tale funzione che restituisce un array booleano che indica se i float hanno una parte frazionaria o meno. Il più vicino che riesco a trovare è np.modf che restituisce le parti frazionarie e integer, ma crea due array mobili (almeno temporaneamente), quindi potrebbe non essere la memoria migliore.

Se sei felice di lavorare in atto, si può provare qualcosa di simile:

>>> np.mod(x, 1, out=x) 
>>> mask = (x == 0) 

Questo dovrebbe risparmiare memoria rispetto all'utilizzo rotondo o piano (dove devi tenere x in giro), ma naturalmente si perde l'originale x.

L'altra opzione è chiedere che venga implementato in Numpy o implementarlo da solo.

+0

Divertente, dovresti dirlo. Stavo chiedendo perché sto pensando di fare proprio questo. –

+0

EDIT: No non sarebbe -> Non sarebbe bitwise_and essere più veloce qui? EDIT: oh, giusto, si applicano solo agli interi, non ai float! Ho passato un po 'troppo tempo facendo JS integer coercian ultimamente ... – Job

1

Avevo bisogno di una risposta a questa domanda per un motivo leggermente diverso: controllo quando posso convertire un'intera serie di numeri in virgola mobile in numeri interi senza perdere dati.

risposta di Hunse quasi funziona per me, se non che io ovviamente non posso usare il trucco sul posto, dal momento che ho bisogno di essere in grado di annullare l'operazione:

if np.all(np.mod(x, 1) == 0): 
    x = x.astype(int) 

Da lì, ho pensato alla seguente opzione che probabilmente è più veloce in molte situazioni:

x_int = x.astype(int) 
if np.all((x - x_int) == 0): 
    x = x_int 

la ragione è che l'operazione di modulo è più lento di sottrazione. Tuttavia, ora facciamo il casting degli interi in anticipo: non so quanto sia veloce questa operazione, relativamente parlando. Ma se la maggior parte degli array sono interi (sono nel mio caso), quest'ultima versione è quasi sicuramente più veloce.

Un altro vantaggio è che è possibile sostituire la surrogazione con qualcosa come np.isclose da verificare con una certa tolleranza (ovviamente si dovrebbe fare attenzione qui, poiché il troncamento non è un arrotondamento corretto!).

x_int = x.astype(int) 
if np.all(np.isclose(x, x_int, 0.0001)): 
    x = x_int 

EDIT: Più lento, ma forse vale la pena a seconda del caso d'uso, è anche la conversione di interi singolarmente se presente.

x_int = x.astype(int) 
safe_conversion = (x - x_int) == 0 
# if we can convert the whole array to integers, do that 
if np.all(safe_conversion): 
    x = x_int.tolist() 
else: 
    x = x.tolist() 
    # if there are _some_ integers, convert them 
    if np.any(safe_conversion): 
     for i in range(len(x)): 
      if safe_conversion[i]: 
       x[i] = int(x[i]) 

Come esempio di dove questo conta: questo funziona per me, perché ho dati sparsi (che significa per lo più zeri) che ho poi convertire in JSON, una volta, e riutilizzare in seguito su un server. Per i galleggianti, ujson converte quelli come [ ...,0.0,0.0,0.0,... ] e per i risultati che risultano in [...,0,0,0,...], risparmiando fino a metà dei numeri di caratteri nella stringa. Ciò riduce il sovraccarico sia sul server (stringhe più corte) che sul client (stringhe più corte, un analisi JSON presumibilmente leggermente più veloce).

+0

Ho appena capito che questa è la mia domanda. Grazie per una bella risposta. –

+1

Prego! :) Mi sono appena reso conto che se alcuni elementi degli elementi possono essere convertiti in modo sicuro, l'overhead aggiunto di farlo vale la pena per me, quindi ho aggiunto il codice per come farlo. – Job

Problemi correlati