Как нарезать 2D Python Array? Сбой: «TypeError: индексы списка должны быть целыми числами, а не кортежем» - PullRequest
14 голосов
/ 10 сентября 2010

У меня есть двумерный массив в модуле numpy, который выглядит так:

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

Я хочу получить фрагмент этого массива, который включает только определенные столбцы элемента. Например, я могу хотеть столбцы 0 и 2:

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

Какой самый Pythonic способ сделать это? (Нет для петель, пожалуйста)

Я думал, что это будет работать:

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

но это приводит к:

TypeError: list indices must be integers, not tuple

Ответы [ 7 ]

17 голосов
/ 10 сентября 2010

Ошибка говорит об этом явно: данные - это не пустой массив, а список списков.

сначала попытайтесь преобразовать его в простой массив:

numpy.array(data)[:,[0,2]]
7 голосов
/ 25 июля 2013

Если вы хотите нарезать 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]]
5 голосов
/ 10 сентября 2010

На самом деле, то, что вы написали, должно работать нормально ... Какую версию 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]])

как и должно ...

3 голосов
/ 22 ноября 2012

Это может быть не то, что вы ищете, но это будет делать.zip (* x) [любые столбцы, которые вам могут понадобиться]

2 голосов

Почему это работает с Numpy, но не со списками Python

Потому что с __getitem__ вы можете программировать свои классы так, чтобы они делали что угодно с : и несколькими аргументами.

Numpy делает это, но встроенные list s этого не делают.

Точнее:

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__ списка, ивстроенные списки не запрограммированы для обработки аргументов кортежа, только целые числа.

1 голос
/ 01 февраля 2012

Остерегайтесь того, что numpy принимает только обычный массив с одинаковым размером для каждого элемента. Вы можете как-то использовать: [a[i][0:2] for i in xrange(len(a))] это довольно уродливо, но это работает.

0 голосов
/ 06 февраля 2017
newArray = data[:,0:2]

или я что-то упустил?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...