Ответ 1
Ошибка говорит это явно: данные не являются массивом numpy, а списком списков.
попробуйте сначала преобразовать его в массив numpy:
numpy.array(data)[:,[0,2]]
У меня есть 2d-массив в модуле numpy, который выглядит так:
data = array([[1,2,3],
[4,5,6],
[7,8,9]])
Я хочу получить фрагмент этого массива, который включает только определенные столбцы элемента. Например, мне могут понадобиться столбцы 0 и 2:
data = [[1,3],
[4,6],
[7,9]]
Каков самый питонический способ сделать это? (Нет для циклов, пожалуйста)
Я думал, что это сработает:
newArray = data[:,[0,2]]
но это приводит к:
TypeError: list indices must be integers, not tuple
Ошибка говорит это явно: данные не являются массивом numpy, а списком списков.
попробуйте сначала преобразовать его в массив numpy:
numpy.array(data)[:,[0,2]]
Если вы хотите разрезать 2D список, следующая функция может помочь
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]]
Собственно, то, что вы написали, должно работать нормально... Какую версию numpy вы используете?
Просто для проверки, следующее должно отлично работать с любой последней версией numpy:
import numpy as np
x = np.arange(9).reshape((3,3)) + 1
print x[:,[0,2]]
Что для меня дает:
array([[1, 3],
[4, 6],
[7, 9]])
как и следовало бы...
Это может быть не то, что вы ищете, но это будет. zip (* x) [любые столбцы, которые могут вам понадобиться]
Почему это работает на Numpy, но не на списках Python
Потому что с помощью __getitem__
вы можете запрограммировать классы, чтобы делать все, что хотите, с помощью :
и нескольких аргументов.
Numpy делает это, но встроенный list
не делает.
Точнее:
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
Затем мы можем открыть объекты среза как:
s = slice(1, 2, 3)
assert s.start == 1
assert s.stop == 2
assert s.step == 3
Итак, когда вы пишете:
[][1, 2]
Python говорит:
TypeError: list indices must be integers, not tuple
потому что вы пытаетесь передать (1, 2)
в список __getitem__
, а встроенные списки не запрограммированы для обработки аргументов кортежа, только целые числа.
Остерегайтесь того, что numpy принимает только обычный массив с одинаковым размером для каждого элемента.
вы можете как-то использовать:
[a[i][0:2] for i in xrange(len(a))]
это довольно уродливо, но оно работает.
newArray = data[:,0:2]
или я что-то не хватает?