ottengo un altro errore di te (utilizzando 1.7.0.dev NumPy):
ValueError: setting an array element with a sequence.
quindi la spiegazione di seguito non può essere corretto per il sistema (o potrebbe anche essere la sbagliata spiegazione per quello che vedo).
In primo luogo, si noti che l'indicizzazione di una riga di una structured array ti dà un oggetto numpy.void
(vedi data type docs)
import numpy as np
dt = np.dtype([('tuple', (int, 2))])
a = np.zeros(3, dt)
print type(a[0]) # = numpy.void
Da quello che ho capito, void
è come una sorta di lista Python dal momento che può contenere oggetti di diversa tipi di dati, il che ha senso poiché le colonne in un array strutturato possono essere tipi di dati diversi.
Se invece di indicizzazione, si fetta la prima fila, si ottiene un ndarray
:
print type(a[:1]) # = numpy.ndarray
Questo è analogo a come le liste Python funzionano:
b = [1, 2, 3]
print b[0] # 1
print b[:1] # [1]
affettare restituisce una versione abbreviata della sequenza originale, ma l'indicizzazione restituisce un elemento (in questo caso, uno int
, sopra, un tipo void
).
Pertanto, quando si suddivide le righe dell'array strutturato, è necessario aspettarsi che si comporti proprio come l'array originale (solo con meno righe). Continuando con il tuo esempio, è ora possibile assegnare ai colonne 'tupla' della prima fila:
a[:1]['tuple'] = (1, 2)
Allora, perché ... non lo fa a[0]['tuple'] = (1, 2)
lavoro?
Bene, ricordare che a[0]
restituisce un oggetto void
. Così, quando si chiama
a[0]['tuple'] = (1, 2) # this line fails
si sta assegnando un tuple
all'elemento 'tupla' di quel void
oggetto. Nota: nonostante il fatto che hai chiamato questo indice 'tupla', è stato memorizzato come ndarray
:
print type(a[0]['tuple']) # = numpy.ndarray
Quindi, questo significa che la tupla ha bisogno di essere gettato in un ndarray
. Ma, l'oggetto void
non può eseguire assegnazioni (questa è solo un'ipotesi) perché può contenere tipi di dati arbitrari, quindi non sa a quale tipo eseguire il cast.Per ovviare a questo si può lanciare l'input da soli:
a[0]['tuple'] = np.array((1, 2))
Il fatto che otteniamo diversi errori suggerisce che la linea di cui sopra potrebbe non funzionare per voi in quanto la fusione indirizzi l'errore che ho ricevuto --- non quello che hai ricevuto .
Addendum:
Allora perché i seguenti lavori?
a[0]['tuple'][:] = (1, 2)
Qui, si sta indicizzazione nella matrice quando si aggiunge [:]
, ma senza di che, sei indicizzazione nell'oggetto void
. In altre parole, a[0]['tuple'][:]
dice "sostituisci gli elementi dell'array memorizzato" (che viene gestito dall'array), a[0]['tuple']
dice "sostituisci l'array memorizzato" (che è gestito da void
).
Epilogo:
Stranamente, l'accesso alla fila (cioè indicizzazione con 0) sembra cadere la matrice di base, ma consente ancora di assegnare alla matrice di base.
print a['tuple'].base is a # = True
print a[0].base is a # = False
a[0] = ((1, 2),) # `a` is changed
Forse void
non è davvero una matrice in modo da non avere una matrice di base, ... ma allora perché lo fa avere un attributo base
?
Suggerimento: quando si invia il codice a SO, si prega di inviare bit che possiamo tagliare e incollare; nel caso di Python, ciò significa usare '#' per i commenti inseriti, non '%'. – DSM
Cose divertenti, vedo anche questo dando lo stesso risultato in entrambi i modi usando 1.6.1 ... –
Un po 'strano, ma 'a [0] [' tuple '] [:] = (1,2)' funziona, forse c'è un indizio lì ... –