2013-03-01 35 views
11

Xuất phát từ một nền tảng của Matlab/Octave, tôi đã cố gắng tìm hiểu một cách sần sùi. Một điều đã vấp ngã tôi nhiều lần là sự khác biệt giữa các vectơ và mảng đa chiều. Đối với câu hỏi này tôi sẽ đưa ra một vấn đề cụ thể mà tôi đang gặp phải, nhưng tôi sẽ có nhiều trách nhiệm nếu ai đó cũng có thể giải thích bức tranh tổng quát hơn đằng sau các mảng đơn chiều theo dạng gọn gàng, tại sao bạn muốn chúng ở nơi đầu tiên, để tránh rắc rối khi trộn đơn và đa chiều mảng, vv Dù sao, câu hỏi:Làm cách nào để duy trì định hướng hàng/cột của vectơ ở dạng khối u?

tôi có một 2-D mảng gọi là X:

X = numpy.arange(10).reshape(2,5) 

và tôi muốn lấy cột cuối cùng của X và lưu nó dưới dạng mảng 2-D khác (ví dụ: vectơ cột) được gọi là Y. Cách duy nhất tôi có thể thực hiện cho điều này là:

Y = numpy.atleast_2d(X[:,4]).T 

nhưng tôi không thích điều đó cho một vài lý do:

  1. tôi không cảm thấy như tôi cần phải nói với nó để transpose vector khi định hướng nên được ngụ ý trong X [:, 4].

  2. Sử dụng atleast_2D dường như quá cồng kềnh khi sử dụng lặp đi lặp lại trong mã nơi tình huống này sẽ xuất hiện rất nhiều. Có vẻ như tôi đang làm gì đó sai.

Vì vậy, trong ngắn hạn, có cách nào tốt hơn không?

Cảm ơn.

+2

'np.atleast_2d (x) .T' cũng có thể được viết' x.reshape (-1, 1) '. Nếu bạn làm điều đó rất nhiều, nó có thể là một ý tưởng tốt để xác định một helper cho nó, 'def ascolumn (x): return x.reshape (-1, 1)'. –

Trả lời

37

Thứ nhất, cách dễ dàng để làm những gì bạn muốn:

Y = X[:,4:] 

Bây giờ, lý do NumPy đã không làm điều này khi bạn đã cố gắng nó trước đã làm với bao mảng làm việc trong Python, và thực sự bằng hầu hết các ngôn ngữ lập trình. Khi bạn viết một cái gì đó như a[4], đó là truy cập phần tử thứ năm của mảng, không cho bạn xem một số phần của mảng ban đầu. Ví dụ: nếu a là một dãy số, thì a[4] sẽ chỉ là một số. Nếu a là mảng hai chiều, tức là một mảng có hiệu quả, thì a[4] sẽ là mảng một chiều. Về cơ bản, hoạt động truy cập một phần tử mảng trả về một cái gì đó với một chiều không nhỏ hơn một mảng ban đầu.

Bây giờ, Python bao gồm điều này được gọi là "ký hiệu slice", được biểu diễn bằng dấu hai chấm, đây là một cách khác để truy cập các phần tử mảng. Thay vì trả về một phần tử (một thứ có kích thước nhỏ hơn một mảng ban đầu), nó trả về một bản sao của một phần của mảng ban đầu. Về cơ bản, a:b đại diện cho danh sách tất cả các phần tử tại chỉ số a (bao gồm) đến b (độc quyền). Hoặc là a hoặc b hoặc cả hai đều có thể được bỏ qua, trong trường hợp này, lát cắt sẽ được chuyển tới đầu tương ứng của mảng.

Điều này có ý nghĩa gì đối với trường hợp của bạn là khi bạn viết X[:,4], bạn có một ký hiệu cắt lát và một ký hiệu chỉ mục thông thường. Ký hiệu slice đại diện cho tất cả các chỉ số dọc theo thứ nguyên đầu tiên (chỉ 0 và 1, vì mảng có hai hàng) và 4 biểu thị phần tử thứ năm dọc theo thứ nguyên thứ hai.Mỗi thể hiện của một chỉ mục thông thường về cơ bản làm giảm kích thước của đối tượng trả về một, do đó, vì X là một mảng 2D, và có một chỉ số thông thường, bạn nhận được kết quả 1D. Numpy chỉ hiển thị mảng 1D dưới dạng vectơ hàng. Bí quyết, nếu bạn muốn tìm ra thứ gì đó có cùng kích thước mà bạn bắt đầu, thì sử dụng tất cả các chỉ mục slice, như tôi đã làm trong ví dụ ở đầu bài đăng này.

Nếu bạn muốn trích xuất cột thứ năm của thứ gì đó có hơn 5 cột tổng số, bạn có thể sử dụng X[:,4:5]. Nếu bạn muốn xem hàng 3-4 và cột 5-7, bạn sẽ làm X[3:5,5:8]. Hy vọng rằng bạn có được ý tưởng.

+0

+1 để được giải thích kỹ lưỡng. – Jan

+0

Điều này rất hữu ích! – RoyalTS

+0

Câu trả lời chính xác hơn một chút có vẻ là 'Y = X [:, 4: 5]', ngay cả khi X xảy ra chỉ có 5 cột. – jolvi

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