2013-07-19 10 views
6

Sto usando un programma esterno per calcolare una matrice scritta in C++ ed interfacciata con python tramite boost::python. Vorrei passare questo array C a numpy, e secondo gli autori questa abilità è già implementata con numpy obj.__array_interface__. Se Io chiamo questo in uno script python e assegnare oggetto C++ per X ottengo il seguente:L'__array_interface__ di Numpy non risponde dict

print X 
#<sprint.Matrix object at 0x107c5c320> 

print X.__array_interface__ 
#<bound method Matrix.__array_interface__ of <sprint.Matrix object at 0x107c5c320>> 

print X.__array_interface__() 
#{'shape': (5, 5), 'data': (4416696960, True), 'typestr': '<f8'} 

print np.array(X) 
#Traceback (most recent call last): 
# File "<string>", line 96, in <module> 
#ValueError: Invalid __array_interface__ value, must be a dict 

Dalla mia comprensione limitata Credo che il problema è X.__array_interface__ non è in realtà tornando nulla senza il (). C'è un modo per passare questi argomenti a np.array in modo esplicito o una soluzione alternativa per questo problema.

Sono davvero abbastanza nuovo nel mixare C++ e python, se questo non ha senso o se devo esporre su qualsiasi parte fammelo sapere!

+0

'np.array' vuole un dizionario. Sembra che 'X .__ array_interface __()' restituisca un dizionario. Quindi non sarebbe 'np.array (X .__ array_interface __())' fallo? – greatwolf

+1

Anche questo era il mio pensiero iniziale, ma 'np.array' vuole un oggetto con il dizionario in' __array_interface__', vedi 'http://docs.scipy.org/doc/numpy/reference/generated/numpy.array.html '. Quindi 'np.array (X .__ array_interface __())' restituisce solo il dizionario. Sfortunatamente 'np.array' è in realtà un' oggetto condiviso 'e mi manca la comprensione per manipolarlo. – Daniel

+1

brutto ma che ne dici di assegnare X .__ array_interface__ = X .__ array_interface __()? Se questo fallisce potresti dover scavare nel C++ e costruire un array numpy su quel lato. –

risposta

2

__array_interface__ deve essere una proprietà (variabile di istanza), non un metodo. Così nel C++, o dovunque l'oggetto 'sprint.Matrix' è definito, modificarlo in modo che invece di avere:

print X.__array_interface__ 
#<bound method Matrix.__array_interface__ of <sprint.Matrix object at 0x107c5c320>> 

avete

print X.__array_interface__ 
#{'shape': (5, 5), 'data': (4416696960, True), 'typestr': '<f8'} 

Un'alternativa sarebbe quella di definire un involucro personalizzato classe:

class SprintMatrixWrapper(object): 
    def __init__(self, sprint_matrix): 
     self.__array_interface__ = sprint_matrix.__array_interface__() 

e poi semplicemente fare:

numpy.array(SprintMatrixWrapper(X)) 
+1

Funziona alla grande! Speravo davvero che ci fosse un modo per alimentare il dizionario in 'np.array'. Darò qualche giorno per accettare la tua risposta. +1 – Daniel