2016-08-02 39 views
7

Ví dụCó chức năng nào trong python có thể thực hiện nghịch đảo của hàm numpy.repeat không?

x = np.repeat(np.array([[1,2],[3,4]]), 2, axis=1) 

mang đến cho bạn

x = array([[1, 1, 2, 2], 
      [3, 3, 4, 4]]) 

nhưng có cái gì đó có thể thực hiện

x = np.*inverse_repeat*(np.array([[1, 1, 2, 2],[3, 3, 4, 4]]), axis=1) 

và mang đến cho bạn

x = array([[1,2],[3,4]]) 
+0

Làm thế nào nói chung của một 'repeat' đang nói gì vậy? Bạn có biết các thông số lặp lại trước thời hạn không? Một số duy nhất lặp lại trên một trục đã biết là dễ dàng. Nhưng lặp lại có thể sử dụng một số khác nhau cho mỗi phần tử. – hpaulj

+0

@hpaulj Như tôi đã nói trong câu hỏi, tôi muốn nghịch đảo chính xác của hàm np.repeat. tức là số lần lặp lại cố định –

+0

Xem câu trả lời của tôi để biết thêm chi tiết về lý do tôi hỏi câu hỏi này. – hpaulj

Trả lời

5

SLIC Regular ing nên hoạt động. Đối với trục bạn muốn ngược lặp lại, sử dụng ::number_of_repetitions

x = np.repeat(np.array([[1,2],[3,4]]), 4, axis=0) 
x[::4, :] # axis=0 
Out: 
array([[1, 2], 
     [3, 4]]) 

x = np.repeat(np.array([[1,2],[3,4]]), 3, axis=1) 

x[:,::3] # axis=1 
Out: 
array([[1, 2], 
     [3, 4]]) 


x = np.repeat(np.array([[[1],[2]],[[3],[4]]]), 5, axis=2) 
x[:,:,::5] # axis=2 
Out: 
array([[[1], 
     [2]], 

     [[3], 
     [4]]]) 
+0

lưu ý rằng cú pháp cắt không cho phép chúng tôi dễ dàng lập trình biểu diễn trục để xóa lặp lại mặc dù –

-1
>>> import numpy as np 
>>> x = np.repeat(np.array([[1,2],[3,4]]), 2, axis=1) 
>>> y=[list(set(c)) for c in x] #This part remove duplicates for each array in tuple. So this will not work for x = np.repeat(np.array([[1,1],[3,3]]), 2, axis=1)=[[1,1,1,1],[3,3,3,3]. Result will be [[1],[3]] 
>>> print y 
[[1, 2], [3, 4]] 

Bạn không cần biết đến trục và lặp lại lượng ...

+0

Mặc dù mã này có thể giúp giải quyết vấn đề, cung cấp thêm ngữ cảnh bổ sung liên quan đến _why_ và/hoặc _how_ nó trả lời câu hỏi sẽ đáng kể cải thiện giá trị lâu dài của nó. Vui lòng [sửa] câu trả lời của bạn để thêm giải thích, bao gồm những hạn chế và giả định áp dụng. –

+1

Tại sao bạn lại cầu kỳ về định dạng của câu trả lời này, nhưng không phải là người khác? Trong trường hợp lặp lại chung, một số loại 'set' hoặc' unique' có thể được yêu cầu. Việc khôi phục một danh sách hiểu trong 'numpy' không được khuyến khích, nhưng đôi khi được yêu cầu. – hpaulj

+0

Ok @TobySpeight Tôi sẽ làm bất cứ điều gì bạn muốn. Xin lỗi vì những sai lầm của tôi vì tôi mới là thành viên. Tôi không biết quy tắc chung. – redratear

0

này nên làm việc, và có chữ ký chính xác giống như np.repeat:

def inverse_repeat(a, repeats, axis): 
    if isinstance(repeats, int): 
     indices = np.arange(a.shape[axis]/repeats, dtype=np.int) * repeats 
    else: # assume array_like of int 
     indices = np.cumsum(repeats) - 1 
    return a.take(indices, axis) 

Edit: thêm hỗ trợ cho mỗi mục lặp đi lặp lại là tốt, tương tự như np.repeat

+0

Ứng dụng tuyệt vời của 'take' - dễ dàng hơn việc xây dựng một bộ chia cắt nhiều trục. – hpaulj

+0

vâng; Tôi đã học được về khá muộn trong sự nghiệp gắt gỏng của tôi, và tôi rạn nứt mỗi khi tôi nhìn lại mã cũ của tôi cố gắng lập trình hành động trên một trục nhất định –

0

Đối với trường hợp chúng ta đều biết trục và lặp lại - và lặp lại là một đại lượng vô hướng (cùng một giá trị cho tất cả các yếu tố), chúng tôi có thể xây dựng một chỉ số cắt như thế này:

In [1117]: a=np.array([[1, 1, 2, 2],[3, 3, 4, 4]]) 
In [1118]: axis=1; repeats=2 

In [1119]: ind=[slice(None)]*a.ndim 
In [1120]: ind[axis]=slice(None,None,a.shape[axis]//repeats) 
In [1121]: ind 
Out[1121]: [slice(None, None, None), slice(None, None, 2)] 
In [1122]: a[ind] 
Out[1122]: 
array([[1, 2], 
     [3, 4]]) 

@Eelco's sử dụng take làm cho nó dễ dàng hơn để tập trung vào một trục, nhưng yêu cầu một danh sách các chỉ mục, không phải một lát.

Nhưng repeat cho phép tính số lần lặp lại khác nhau.

In [1127]: np.repeat(a1,[2,3],axis=1) 
Out[1127]: 
array([[1, 1, 2, 2, 2], 
     [3, 3, 4, 4, 4]]) 

Biết axis=1repeats=[2,3] chúng ta nên xây dựng thể quyền take lập chỉ mục (có lẽ với cumsum). Cắt lát sẽ không hoạt động.

Nhưng nếu chúng tôi chỉ biết trục và lặp lại không xác định thì có thể chúng tôi cần một số loại hoạt động unique hoặc set như trong câu trả lời @redratear's.

In [1128]: a2=np.repeat(a1,[2,3],axis=1) 
In [1129]: y=[list(set(c)) for c in a2] 
In [1130]: y 
Out[1130]: [[1, 2], [3, 4]] 

Một giải pháp take với danh sách repeats. Điều này sẽ chọn cuối cùng của mỗi khối lặp lại:

In [1132]: np.take(a2,np.cumsum([2,3])-1,axis=1) 
Out[1132]: 
array([[1, 2], 
     [3, 4]]) 

Câu trả lời đã xóa sử dụng unique; đây là hàng của tôi bằng cách sử dụng hàng unique

In [1136]: np.array([np.unique(row) for row in a2]) 
Out[1136]: 
array([[1, 2], 
     [3, 4]]) 

unique được tốt hơn so với set để sử dụng này vì nó duy trì trật tự phần tử. Có một vấn đề khác với unique (hoặc thiết lập) - điều gì xảy ra nếu giá trị ban đầu có giá trị lặp lại, ví dụ: [[1,2,1,3],[3,3,4,1]].

Đây là trường hợp rất khó để suy ra mẫu lặp lại từ kết quả. Tôi phải xem xét tất cả các hàng đầu tiên.

In [1169]: a=np.array([[2,1,1,3],[3,3,2,1]]) 
In [1170]: a1=np.repeat(a,[2,1,3,4], axis=1) 
In [1171]: a1 
Out[1171]: 
array([[2, 2, 1, 1, 1, 1, 3, 3, 3, 3], 
     [3, 3, 3, 2, 2, 2, 1, 1, 1, 1]]) 

Nhưng cumsum trên lặp lại biết giải quyết nó độc đáo:

In [1172]: ind=np.cumsum([2,1,3,4])-1 
In [1173]: ind 
Out[1173]: array([1, 2, 5, 9], dtype=int32) 
In [1174]: np.take(a1,ind,axis=1) 
Out[1174]: 
array([[2, 1, 1, 3], 
     [3, 3, 2, 1]]) 
Các vấn đề liên quan