2015-03-02 18 views
5

Tôi có mảng numpy trong Python là n-by-n (trong ví dụ là 3-by-3) và chứa giá trị bằng không ở tất cả các vị trí chéo. ví dụ:Sắp xếp mảng bằng Python mà không sửa đổi các vị trí phần tử cụ thể

array([[ 0. , -0.65 , 1.3 , 0.56], 
     [ 0.45 , 0. , 0.54, 43 ], 
     [ 0.5 , 0.12 , 0. , 7 ] 
     [ 0.2 , 0.3 , 0.4 , 0 ]]) 

Có thể sắp xếp mảng mà không sửa đổi vị trí chéo để trông giống như bên dưới không? Bởi vì tất cả các hàm phân loại sẽ tính đến "số không" tồn tại ở các vị trí chéo và sẽ thay đổi vị trí tương đối của chúng.

array([[ 0. , 1.3 , 0.56 , -0.65], 
     [ 43 , 0. , 0.54 , 0.45 ], 
     [ 7 , 0.5 , 0. , 0.12 ] 
     [ 0.4 , 0.3 , 0.2 , 0 ]]) 

Nếu không thể thực hiện thao tác trên, thì giá trị tối đa N và chỉ mục tương ứng của chúng trong mỗi hàng có thể đủ.

Cho đến bây giờ tôi đã cố gắng sắp xếp và argsort nhưng không có kết quả.

+0

Tôi nghĩ có lỗi đánh máy ở hàng cuối cùng. Bạn đang thiếu 0, –

+0

thnx. sửa chữa –

+0

Mảng bây giờ là 3x4 ... – FuzzyDuck

Trả lời

1

Phương pháp đơn giản nhất là để loại bỏ các zero, sắp xếp, sau đó thêm zero trở lại dọc theo đường chéo:

>>> a = [[0,1,2],[3,0,0],[5,6,0]] 
>>> no_zeroes = [r[:i] + r[i+1:] for i, r in enumerate(a)] 
>>> no_zeroes 
[[1, 2], [3, 0], [5, 6]] 
>>> sorted_no_zeroes = [sorted(r, reverse=True) for r in no_zeroes] 
>>> sorted_no_zeroes 
[[2, 1], [3, 0], [6, 5]] 
>>> sorted_with_zeroes = [r[:i] + [0] + r[i:] for i, r in enumerate(sorted_no_zeroes)] 
>>> sorted_with_zeroes 
[[0, 2, 1], [3, 0, 0], [6, 5, 0]] 

bọc vào một chức năng:

>>> def sort_ignoring_zeroes(a): 
... s = [sorted(r[:i] + r[i+1:], reverse=True) for i, r in enumerate(a)] 
... return [r[:i] + [0] + r[i:] for i, r in enumerate(s)] 
... 
>>> sort_ignoring_zeroes(
      [[ 0. , 1.3 , 0.56 , -0.65], 
...  [ 43 , 0. , 0.54 , 0.45], 
...  [ 7 , 0.5 , 0. , 0.12]]) 
[[0, 1.3, 0.56, -0.65], 
[43, 0, 0.54, 0.45], 
[7, 0.5, 0, 0.12]] 
>>> 
+1

Tôi đã suy nghĩ có thể là một thao tác đơn giản và chỉ trả về các chỉ mục của n giá trị lớn nhất của mỗi hàng. Tôi đang cố gắng này: idx = (-arr) .argsort() [: n] nhưng vấn đề là nó chỉ hoạt động nếu n bằng kích thước của mảng N-by-N –

2

Tôi là một chút muộn để câu hỏi này, nhưng nếu bạn đang tìm giải pháp NumPy-only, bạn có thể thay thế inf cho đường chéo của mình, sắp xếp theo thứ tự bạn đã chọn và sau đó trộn cột inf trở lại đường chéo:

In [189]: a = np.array([[ 0. , -0.65 , 1.3 , 0.56], 
    .....:  [ 0.45 , 0. , 0.54, 43 ], 
    .....:  [ 0.5 , 0.12 , 0. , 7 ], 
    .....:  [ 0.2 , 0.3 , 0.4 , 0 ]]) 

In [190]: np.fill_diagonal(a,np.inf) 

In [191]: a.sort() 

In [192]: a = a[:,::-1] 

In [193]: for i in range(1,len(a)): 
    .....:   a[i,:i+1] = np.roll(a[i,:i+1], i) 
    .....:  

In [194]: np.fill_diagonal(a, 0) 

In [195]: a 
Out[195]: 
array([[ 0. , 1.3 , 0.56, -0.65], 
    [ 43. , 0. , 0.54, 0.45], 
    [ 7. , 0.5 , 0. , 0.12], 
    [ 0.4 , 0.3 , 0.2 , 0. ]]) 
+0

cảm ơn, cả hai dường như hoạt động –

+0

Điều này không làm việc, chỉ cần trao đổi các giá trị phá hủy sắp xếp. Việc triển khai với 'np.triu_indices' có thể sẽ hoạt động. – Daniel

+0

Cảm ơn, @Ophion - bạn hoàn toàn đúng. Tôi nghĩ rằng tôi đã cố định nó ngay bây giờ, bằng cách sử dụng 'np.roll' trên lát thích hợp. – xnx

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