Converte array numpy in tupla


108

Nota: questo richiede il contrario della normale conversione da tupla ad array.

Devo passare un argomento a una funzione (c ++ racchiusa) come una tupla annidata. Ad esempio, quanto segue funziona

X = MyFunction( ((2,2),(2,-2)) )

mentre i seguenti non lo fanno

X = MyFunction( numpy.array(((2,2),(2,-2))) )
X = MyFunction( [[2,2],[2,-2]] )

Sfortunatamente, l'argomento che vorrei usare mi viene come un array numpy. Quell'array ha sempre dimensioni 2xN per alcuni N, che possono essere abbastanza grandi.

C'è un modo semplice per convertirlo in una tupla? So che potrei semplicemente eseguire il loop, creando una nuova tupla, ma preferirei che ci fosse un buon accesso fornito dall'array numpy.

Se non è possibile farlo bene come spero, qual è il modo più carino per farlo in loop, o altro?

Risposte:


157
>>> arr = numpy.array(((2,2),(2,-2)))
>>> tuple(map(tuple, arr))
((2, 2), (2, -2))

29
Quindi, per un semplice array 1-dtuple(arr)
FindOutIslamNow

26

Ecco una funzione che lo farà:

def totuple(a):
    try:
        return tuple(totuple(i) for i in a)
    except TypeError:
        return a

E un esempio:

>>> array = numpy.array(((2,2),(2,-2)))
>>> totuple(array)
((2, 2), (2, -2))

1
Bella generalizzazione. Come principiante di Python, tuttavia, mi chiedo se sia considerato uno stile buono usare eccezioni per una condizione che è quasi comune come lo stato non eccezionale. Almeno in c ++, il controllo del flusso tramite eccezioni è generalmente disapprovato. Sarebbe meglio provare se type(a)==numpy.ndarray?
Mike

9
Questo è abbastanza comune in Python a causa del concetto di "dattilografia" e EAFT, più qui: docs.python.org/glossary.html#term-duck-typing . Il vantaggio di questo approccio è che convertirà qualsiasi sequenza annidata in tuple annidate, non solo un array. Una cosa che avrei dovuto fare che ho corretto è specificare quali errori voglio che vengano gestiti dal blocco eccetto.
Bi Rico

3
In C ++, le eccezioni sono lente rispetto ai condizionali per una serie di motivi. In Python, sono più o meno gli stessi in termini di prestazioni: questo è uno dei posti in cui dobbiamo controllare le nostre intuizioni C ++ alla porta.
dbn

8

Non ero soddisfatto, quindi ho finalmente usato questo:

>>> a=numpy.array([[1,2,3],[4,5,6]])
>>> a
array([[1, 2, 3],
       [4, 5, 6]])

>>> tuple(a.reshape(1, -1)[0])
(1, 2, 3, 4, 5, 6)

Non so se sia più veloce, ma sembra più efficace;)


3
Non era la forma che volevo per la tupla.
Mike

5

Un'altra opzione

tuple([tuple(row) for row in myarray])

Se stai passando gli array NumPy alle funzioni C ++, potresti anche voler usare Cython o SWIG.


Quello non si converte in tupla. Converte in un elenco?
Peter,

Hai provato? Crea una tupla quando corro. Notare che l'ultima funzione chiamata è tupla, che restituisce una tupla. Se hai solo la parte [...] senza la tupla esterna, otterrai un elenco di tuple.
Greg von Winckel

esiste un metodo più veloce?
Vicrobot

1
Potresti evitare di creare l'intermedio listomettendo le parentesi quadre, ovvero utilizzandotuple(tuple(row) for row in myarray)
norok2

1

Se ti piacciono i tagli lunghi, ecco un altro modo in cui tuple (tuple (a_m.tolist ()) per a_m in a)

from numpy import array
a = array([[1, 2],
           [3, 4]])
tuple(tuple(a_m.tolist()) for a_m in a )

L'output è ((1, 2), (3, 4))

Nota solo (tuple (a_m.tolist ()) per a_m in a) fornirà un'espressione del generatore. Un po 'ispirato dal commento di @ norok2 alla risposta di Greg von Winckel

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.