2017-03-15 15 views

Trả lời

11
b = a[(slice(None),) * k + (i,)] 

Xây dựng các tuple lập chỉ mục bằng tay.

Theo tư liệu trong Python language reference, một biểu hiện của hình thức

a[:, :, :, :, :, i] 

được chuyển thành

a[(slice(None), slice(None), slice(None), slice(None), slice(None), i)] 

Chúng ta có thể đạt được hiệu quả tương tự bằng cách xây dựng tuple trực tiếp thay vì sử dụng ký hiệu cắt. (Có caveat nhỏ mà xây dựng các tuple trực tiếp sản xuất a[(i,)] thay vì a[i] cho k=0, nhưng NumPy xử lý những giống nhau cho vô hướng i.)

+0

.Tôi sẽ vui vẻ sao chép - & - dán này, nhưng một liên kết đến tài liệu có lẽ vẫn hữu ích. –

+0

ký hiệu cắt lát, ví dụ: 'a []' chỉ là cú pháp đường cho một lệnh gọi '__getitem__' chuyển nó thành một bộ tuple, trong trường hợp này là một đối tượng slice (ký hiệu': 'là cú pháp suger cho đối tượng' slice') –

+0

. cũng đánh vần rằng 'b [np.index_exp [:] * k + np.index_exp [i]]', có thể dễ đọc hơn một chút – Eric

3

Tôi không chắc chắn nếu nó sẽ làm việc cho k mờ nhưng nó cho 2 mờ

a.take(i,axis=k) 
+2

Điều này có bất lợi khi tạo bản sao thay vì một khung nhìn. – user2357112

+0

@ user2357112: Huh, đó là một chút đáng ngạc nhiên – Eric

1

về cơ bản, bạn muốn để có thể lập trình tạo ra các tuple :, :, :, :, :, i, ... để vượt qua nó trong khi chỉ số của a. Thật không may, bạn không thể đơn giản sử dụng phép nhân tuple bình thường trên toán tử kết nối trực tiếp (tức là, (:,) * k sẽ không hoạt động để tạo ra một bộ gồm k toán tử kết nối). Tuy nhiên, bạn có thể lấy một thể hiện của một "dấu hai chấm" bằng cách sử dụng colon = slice(None). Sau đó, bạn có thể làm b = a[(colon,) * k + (i,)], có hiệu quả sẽ lập chỉ mục a ở cột thứ i của thứ nguyên k.

Bao bì này trong một hàm, bạn sẽ nhận được:

def nDimSlice(a, k, i): 
    colon = slice(None) 
    return a[(colon,) * k + (i,)] 
+2

lát thêm sau khi 'i' là không cần thiết như xa như là lo ngại là có liên quan – Aaron

+0

@ Aaron Cảm ơn, tôi đã không biết! – user108471

0

Tôi không chắc chắn nếu phương pháp này sẽ tạo ra toàn bộ một bản sao của mảng *, nhưng tôi sẽ phải mất một lát các hoán ma trận để có được trục thứ k:

import numpy as np 

def get_slice(arr, k, i): 
    if k >= arr.ndim: #we need at least k dimensions (0 indexed) 
     raise ValueError("arr is of lower dimension than {}".format(k)) 

    axes_reorder = list(range(arr.ndim)) #order of axes for transpose 
    axes_reorder.remove(k) #remove original position of k 
    axes_reorder.insert(0,k) #insert k at beginning of order 

    return arr.transpose(axes_reorder)[i] #k is first axis now 

này cũng có thêm tiền thưởng của kiểm tra dễ dàng hơn số lượng kích thước trước khi thử các slice.

* theo docs, chế độ xem bộ nhớ được tạo bất cứ khi nào có thể.

1

đây là một mục cuối có thể xử lý đối số trục tiêu cực mà không cần phải biết hình dạng của toán hạng của nó trước:

def put_at(inds, axis=-1, slc=(slice(None),)): 
    return (axis<0)*(Ellipsis,) + axis*slc + (inds,) + (-1-axis)*slc 

Để được sử dụng như trong

a[put_at(ind_list,axis=axis)] 

ind_list có thể là một đại lượng vô hướng như trong trường hợp của bạn hoặc một cái gì đó thú vị hơn là tốt.

Đã sao chép từ this nhận xét của tôi.

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