Python __getitem__ mảng 2d

Gần đây, tôi tình cờ thấy numpy hỗ trợ làm việc với mảng đa chiều trong Python. Mảng đa chiều chính xác là gì?

Xét một vectơ trong không gian ba chiều được biểu diễn dưới dạng một danh sách, e. g. v=[8, 5, 11]. Đây là mảng một chiều, vì chỉ có một chỉ mục, nghĩa là mọi phần tử đều có thể được truy cập bằng một chỉ mục, i. e. v[i] là đủ để truy cập tất cả các phần tử và i là chỉ mục. Ngay cả một vectơ trong không gian 11 chiều là một mảng một chiều

Rõ ràng, thuật ngữ này khó hiểu, vì thuật ngữ thứ nguyên có thể đề cập đến không gian hoặc mảng. Do đó, người ta sử dụng thuật ngữ trục khi đề cập đến kích thước của một mảng. Số lượng các trục được gọi là thứ hạng. Đối với ví dụ trên, chúng ta có thể nói rằng vectơ trong không gian ba chiều được biểu diễn bằng một mảng có một trục, một mảng có bậc một

Có một thuật ngữ chính xác, chúng ta có thể chuyển sang mảng có hạng hai. Ví dụ: ma trận 3x3 mô tả phép quay của vectơ trong không gian ba chiều có thể được biểu diễn dưới dạng mảng hạng hai. Trong ký hiệu toán học, chúng ta gọi các phần tử của ma trận là Aij. Trong Python đơn giản, chúng ta có thể biểu diễn một ma trận như một danh sách các danh sách

>>> A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> i, j = 1, 2
>>> A[i][j]
6

Điều này hoạt động miễn là chúng tôi giới hạn bản thân với các phần tử riêng lẻ trong ma trận, nhưng giả sử chúng tôi trích xuất ma trận con 2x2 bao gồm các phần tử 5, 6, 8, 9 bằng cách sử dụng phép cắt. Chúng tôi ước chúng tôi có thể chỉ cần gõ

>>> A[1:3][1:3]   # We want to get [[5, 6], [8, 9]]
[[7, 8, 9]]

Sử dụng cắt một trục, không thể đạt được kết quả mong muốn chỉ với một biểu thức nhỏ. Do đó Python hỗ trợ cú pháp cắt đa trục, nghĩa là chúng ta có thể viết biểu thức như

>>> A[1:3][1:3]   # We want to get [[5, 6], [8, 9]]
[[7, 8, 9]]
0 mà không nhận được thông báo lỗi. Tuy nhiên, Python không đi kèm với mảng nhiều trục, nó chỉ hỗ trợ cú pháp. Để hiểu rõ hơn cách Pythons hỗ trợ cú pháp cắt đa trục, lớp nhỏ sau đây sẽ hiển thị các đối số được truyền cho phương thức
>>> A[1:3][1:3]   # We want to get [[5, 6], [8, 9]]
[[7, 8, 9]]
1

>>> class Foo:
..   def __getitem__[self, *args]:
..     print args
...
>>> x = Foo[]
>>> x[1]
[1,]
>>> x[1:]
[slice[1, 2147483647, None],]
>>> x[1:, :]
[[slice[1, None, None], slice[None, None, None]],]
>>> x[1:, 20:10:-2, ...]
[[slice[1, None, None], slice[20, 10, -2], Ellipsis],]

[Lưu ý kết quả khác nhau cho trục đầu tiên trong

>>> A[1:3][1:3]   # We want to get [[5, 6], [8, 9]]
[[7, 8, 9]]
2 và
>>> A[1:3][1:3]   # We want to get [[5, 6], [8, 9]]
[[7, 8, 9]]
3. Đối tượng lát cắt
>>> A[1:3][1:3]   # We want to get [[5, 6], [8, 9]]
[[7, 8, 9]]
4 chỉ xảy ra khi một phương thức được gọi bằng một trục duy nhất. Giả định của tôi là đây là hành vi khi các lát cắt lần đầu tiên được triển khai vào Python và vì lý do tương thích ngược, không thể thay đổi điều này. Tôi đã thử điều tương tự trong Python 3. 0 và hành vi nhất quán cho các lát trục đơn và nhiều trục, tôi. e. đối tượng lát cắt luôn là
>>> A[1:3][1:3]   # We want to get [[5, 6], [8, 9]]
[[7, 8, 9]]
5, vì lẽ ra nó phải như vậy. ]

Giờ đây, thư viện mảng đa trục có trách nhiệm làm điều gì đó hữu ích với các đối số này. numpy sử dụng các đối số này để trả về kết quả mong muốn

>>> from numpy import *
>>> B = array[A]
>>> B
array[[[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]]]
>>> B[1:3, 1:3]
array[[[5, 6],
       [8, 9]]]
>>> B[1:3, 1:3].tolist[]
[[5, 6], [8, 9]]

Vì python không đi kèm với các mảng nhiều trục, nên đối tượng

>>> A[1:3][1:3]   # We want to get [[5, 6], [8, 9]]
[[7, 8, 9]]
6 và
>>> A[1:3][1:3]   # We want to get [[5, 6], [8, 9]]
[[7, 8, 9]]
7 hầu như không bao giờ được sử dụng một cách rõ ràng trong các chương trình Python. Tuy nhiên, trong ví dụ sau, một danh sách và một đối tượng
>>> A[1:3][1:3]   # We want to get [[5, 6], [8, 9]]
[[7, 8, 9]]
6 được chuyển đến một trình tạo lặp lại danh sách được cắt lát

>>> def mygen[lst, s=slice[None]]:
..   for e in lst[s]:
..     yield e
.. 
>>> for n in mygen[range[10]]: print n,
.. 
0 1 2 3 4 5 6 7 8 9
>>> for n in mygen[range[10], slice[7]]: print n,
.. 
0 1 2 3 4 5 6
>>> for n in mygen[range[10], slice[8, 1, -2]]: print n,
.. 
8 6 4 2

Sử dụng numpy, một đối tượng

>>> A[1:3][1:3]   # We want to get [[5, 6], [8, 9]]
[[7, 8, 9]]
6 rõ ràng có thể rất hữu ích. Trong ví dụ thực tế sau [sử dụng numpy], tôi phải xây dựng một ma trận con. thay vì viết

Chủ Đề