2010-09-09 7 views
13

que tienen una matriz 2D en el módulo numpy que se parece a:Cómo cortar una matriz de Python 2D? Falla con: "TypeError: índices de la lista deben ser enteros, no tupla"

data = array([[1,2,3], 
       [4,5,6], 
       [7,8,9]]) 

Quiero conseguir una rebanada de esta matriz que sólo incluye cierta columnas de elemento. Por ejemplo es posible que quiera columnas 0 y 2:

data = [[1,3], 
     [4,6], 
     [7,9]] 

¿Cuál es la forma más Pythonic para hacer esto? (No para los bucles, por favor)

pensé que esto funcionaría:

newArray = data[:,[0,2]] 

pero resulta en una:

TypeError: list indices must be integers, not tuple 

Respuesta

5

En realidad, lo que ha escrito debería funcionar bien ... ¿Qué versión de numpy estás usando?

Sólo para verificar, lo siguiente debe funcionar perfectamente con cualquier versión reciente de numpy:

import numpy as np 
x = np.arange(9).reshape((3,3)) + 1 
print x[:,[0,2]] 

que, para mí, se obtiene:

array([[1, 3], 
     [4, 6], 
     [7, 9]]) 

como debería ...

16

El error lo dice explícitamente: los datos no son una matriz numpy sino una lista de listas.

tratan de convertirlo en una matriz numpy primero:

numpy.array(data)[:,[0,2]] 
+1

Buena atrapada! Me inclino ante tus habilidades de depuración psíquica. :) –

1

Mira que numpy sólo aceptan matriz regular con el mismo tamaño para cada elementos. de alguna manera puede usar: [a[i][0:2] for i in xrange(len(a))] es bastante feo, pero funciona.

+1

Numpy acepta cualquier combinación de sectores, enteros y matrices. Las matrices no tienen que ser del mismo tamaño, pero deberían transmitirse entre sí. Y creo que la expresión que buscas es '[[fila [0], fila [2]] para fila en datos]'. –

3

Esto puede no ser lo que estás buscando, pero esto es lo que harías. postal (* x) [lo que pueda necesitar columnas]

8

Si desea desea cortar 2D lista la función siguiente puede ayudar a

def get_2d_list_slice(self, matrix, start_row, end_row, start_col, end_col): 
    return [row[start_col:end_col] for row in matrix[start_row:end_row]] 
+0

¡Genial! Buena codificación aquí! No debería ser el comienzo de 0 –

2

Por qué funciona en Numpy pero no las listas de Python

Porque con __getitem__ puede programar sus clases para hacer lo que quiera con : y argumentos múltiples.

Numpy lo hace, pero el list incorporado no lo hace.

Más precisamente:

class C(object): 
    def __getitem__(self, k): 
     return k 

# Single argument is passed directly. 
assert C()[0] == 0 

# Multiple indices generate a tuple. 
assert C()[0, 1] == (0, 1) 

# Slice notation generates a slice object. 
assert C()[1:2:3] == slice(1, 2, 3) 

# If you omit any part of the slice notation, it becomes None. 
assert C()[:] == slice(None, None, None) 
assert C()[::] == slice(None, None, None) 
assert C()[1::] == slice(1, None, None) 
assert C()[:2:] == slice(None, 2, None) 
assert C()[::3] == slice(None, None, 3) 

# Tuple with a slice object: 
assert C()[:, 1] == (slice(None, None, None), 1) 

# Ellipsis class object. 
assert C()[...] == Ellipsis 

Podemos entonces abrimos objetos de división como:

s = slice(1, 2, 3) 
assert s.start == 1 
assert s.stop == 2 
assert s.step == 3 

Por eso es que cuando escribe: dice

[][1, 2] 

Python:

TypeError: list indices must be integers, not tuple 

ya que están tratando de pasar (1, 2) a la lista de __getitem__, y las listas incorporadas no están programados para hacer frente a los argumentos de tupla, sólo enteros.

0
newArray = data[:,0:2] 

o me está faltando algo?

Cuestiones relacionadas