2010-09-09 30 views
13

Tôi có một mảng 2ngày trong module NumPy trông giống như:Làm thế nào để lát một mảng Python 2D? Không thành công với: "Lỗi Loại: chỉ số danh sách phải là số nguyên, không tuple"

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

Tôi muốn có được một lát mảng này chỉ bao gồm một số các cột của phần tử. Ví dụ: tôi có thể muốn các cột 0 và 2:

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

Cách Pythonic nhất để làm điều này là gì? (Không cho vòng hài lòng)

Tôi nghĩ điều này sẽ làm việc:

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

nhưng nó kết quả trong một:

TypeError: list indices must be integers, not tuple 

Trả lời

5

Trên thực tế, những gì bạn đã viết nên chỉ làm việc tốt ... Phiên bản nào của numpy bạn đang sử dụng?

Chỉ cần để xác minh, sau đây nên làm việc một cách hoàn hảo với bất kỳ phiên bản gần đây của NumPy:

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

nào, đối với tôi, sản lượng:

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

như mong muốn ...

16

Lỗi nói nó rõ ràng: dữ liệu không phải là một mảng numpy nhưng một danh sách các danh sách.

cố gắng chuyển nó sang một mảng NumPy đầu tiên:

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

Rất thú vị! Tôi cúi đầu với khả năng gỡ lỗi tâm linh của bạn! :) –

1

Cẩn thận NumPy rằng chỉ chấp nhận mảng thường xuyên với các kích thước tương tự cho mỗi yếu tố. bạn bằng cách nào đó có thể sử dụng: [a[i][0:2] for i in xrange(len(a))] nó khá xấu xí nhưng nó hoạt động.

+1

Numpy chấp nhận bất kỳ sự kết hợp nào của các lát, số nguyên và mảng. Các mảng không cần phải có cùng kích thước, nhưng chúng sẽ phát sóng với nhau. Và tôi tin rằng biểu thức bạn đang tìm kiếm là '[[hàng [0], hàng [2]] cho hàng trong dữ liệu]'. –

3

Đây có thể không phải là những gì bạn đang tìm kiếm nhưng điều này sẽ thực hiện. zip (* x) [bất cứ cột mà bạn có thể cần]

8

Nếu bạn muốn cắt 2D danh sách chức năng sau có thể giúp

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

Tuyệt vời! Tốt mã hóa ở đây! Không nên là sự khởi đầu của 0 –

2

Tại sao nó hoạt động trên NumPy nhưng không phải danh sách Python

Vì với __getitem__ bạn có thể lập trình cho bạn các lớp để làm bất cứ điều gì bạn muốn với : và nhiều đối số.

Numpy thực hiện điều này, nhưng được xây dựng trong list s thì không.

Chính xác hơn:

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 

Sau đó chúng tôi có thể mở đối tượng lát như:

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

Vì vậy, đó là lý do tại sao khi bạn viết:

[][1, 2] 

Python nói:

TypeError: list indices must be integers, not tuple 

vì bạn đang cố gắng vượt qua (1, 2) vào danh sách __getitem__ của danh sách và danh sách được tích hợp sẵn không được lập trình để xử lý đối số tuple, chỉ số nguyên.

0
newArray = data[:,0:2] 

hoặc tôi đang thiếu gì đó?

Các vấn đề liên quan