me sale un error diferente de lo que hacen (usando 1.7.0.dev numpy):
ValueError: setting an array element with a sequence.
por lo que la explicación a continuación pueden no estar correcto para su sistema (o incluso podría ser el mal explicación de lo que veo).
En primer lugar, observe que la indexación de una fila de un structured array le da un objeto numpy.void
(ver data type docs)
import numpy as np
dt = np.dtype([('tuple', (int, 2))])
a = np.zeros(3, dt)
print type(a[0]) # = numpy.void
Por lo que entiendo, void
es algo así como una lista de Python, ya que puede contener objetos de diferentes tipos de datos, lo cual tiene sentido ya que las columnas en una matriz estructurada pueden ser tipos de datos diferentes.
Si, en lugar de indexación, que se mire a cabo la primera fila, se obtiene una ndarray
:
print type(a[:1]) # = numpy.ndarray
Esto es análogo a la forma en las listas de Python funcionan:
b = [1, 2, 3]
print b[0] # 1
print b[:1] # [1]
rebanar devuelve una versión abreviada de la secuencia original, pero la indexación devuelve un elemento (aquí, un int
; arriba, un tipo void
).
Por lo tanto, cuando corta en las filas de la matriz estructurada, debe esperar que se comporte como su matriz original (solo con menos filas). Continuando con su ejemplo, ahora puede asignar a las columnas de tupla '' de la primera fila:
a[:1]['tuple'] = (1, 2)
Así, ... ¿Por qué no a[0]['tuple'] = (1, 2)
trabajo?
Bien, recuerde que a[0]
devuelve un objeto void
. Por lo tanto, cuando se llama a
a[0]['tuple'] = (1, 2) # this line fails
que está asignando un tuple
al elemento 'tupla' de ese void
objeto. Nota: a pesar del hecho que ha llamado a este índice 'tupla', se almacena como un ndarray
:
print type(a[0]['tuple']) # = numpy.ndarray
lo tanto, esto significa que la tupla debe ser echado en una ndarray
. Pero, el objeto void
no puede enviar asignaciones (esto es sólo una suposición) porque puede contener tipos de datos arbitrarios, por lo que no sabe de qué tipo se va a convertir.Para evitar esto se puede echar la entrada a sí mismo:
a[0]['tuple'] = np.array((1, 2))
El hecho de que tenemos diferentes errores sugiere que la línea anterior podría no funcionar para ti desde la fundición direcciones el error que he recibido --- no la que usted recibió .
Adición:
Así que ¿por qué el siguiente trabajo?
a[0]['tuple'][:] = (1, 2)
aquí, estás indexar en la matriz cuando se agrega [:]
, pero sin eso, usted es la indexación en el objeto void
. En otras palabras, a[0]['tuple'][:]
dice "reemplazar los elementos de la matriz almacenada" (que maneja la matriz), a[0]['tuple']
dice "reemplazar la matriz almacenada" (que es manejada por void
).
Epílogo:
Curiosamente, el acceso a la fila (es decir, con la indexación 0) parece caer la matriz de base, pero todavía le permite asignar a la matriz de base.
print a['tuple'].base is a # = True
print a[0].base is a # = False
a[0] = ((1, 2),) # `a` is changed
Tal void
no es realmente una matriz por lo que no cuenten con un conjunto de base, pero entonces ... ¿por qué tener un atributo base
?
Consejo: al publicar código en SO, publique los bits que podemos cortar y pegar; en el caso de Python, eso significa usar '#' para los comentarios insertados, no '%'. – DSM
Cosas divertidas, también veo que esto da el mismo resultado de cualquier manera usando 1.6.1 ... –
Un poco extraño, pero 'a [0] ['tuple'] [:] = (1,2)' funciona, tal vez hay una pista allí ... –