python - একাধিক মাত্রা সহ numpy.argsort এর জন্য আক্রমণকারীকে বাছাই করুন




arrays sorting (2)

numpy.argsort ডক্স numpy.argsort

রিটার্নস:
সূচি_আররে: নাদারেরে, সূচকগুলির অ্যারে যা নির্দিষ্ট অক্ষের সাথে একটি সাজান। যদি একটি দ্বিমাত্রিক হয় তবে a[index_array] একটি সাজানো একটি প্রদান করে।

বাছাই করা অ্যারে ফিরে পেতে আমি কীভাবে একাধিক numpy.argsort অ্যারের জন্য numpy.argsort এর ফলাফল প্রয়োগ করতে পারি? (কেবলমাত্র 1-D বা 2-D অ্যারে নয়; এটি কোনও এন-ডাইমেনশনাল অ্যারে হতে পারে যেখানে এন কেবল রানটাইমের সময় পরিচিত)

>>> import numpy as np
>>> np.random.seed(123)
>>> A = np.random.randn(3,2)
>>> A
array([[-1.0856306 ,  0.99734545],
       [ 0.2829785 , -1.50629471],
       [-0.57860025,  1.65143654]])
>>> i=np.argsort(A,axis=-1)
>>> A[i]
array([[[-1.0856306 ,  0.99734545],
        [ 0.2829785 , -1.50629471]],

       [[ 0.2829785 , -1.50629471],
        [-1.0856306 ,  0.99734545]],

       [[-1.0856306 ,  0.99734545],
        [ 0.2829785 , -1.50629471]]])

আমার জন্য এটি পরিবর্তে sort() ব্যবহার করার বিষয় নয়; আমার আরেকটি অ্যারে B এবং আমি যথাযথ অক্ষ বরাবর np.argsort(A) এর ফলাফল ব্যবহার করে B অর্ডার করতে চাই। নিম্নলিখিত উদাহরণ বিবেচনা করুন:

>>> A = np.array([[3,2,1],[4,0,6]])
>>> B = np.array([[3,1,4],[1,5,9]])
>>> i = np.argsort(A,axis=-1)
>>> BsortA = ???             
# should result in [[4,1,3],[5,1,9]]
# so that corresponding elements of B and sort(A) stay together

দেখে মনে হচ্ছে এই কার্যকারিতাটি ইতিমধ্যে নম্পিতে একটি বর্ধনের অনুরোধ


আমাদের কেবল সূচকগুলিতে সেই সূচকের অ্যারে সহ advanced-indexing ব্যবহার করতে হবে। আমরা সমস্ত অক্ষ বরাবর রেঞ্জ অ্যারেগুলির উন্মুক্ত গ্রিড তৈরি করতে np.ogrid ব্যবহার করতে পারি এবং তারপরে ইনপুট অক্ষগুলির সাথে কেবল ইনপুট অক্ষের জন্য প্রতিস্থাপন করতে পারি। অবশেষে, পছন্দসই আউটপুট জন্য সূচকগুলি সহ ডেটা অ্যারেতে সূচক। সুতরাং, মূলত, আমাদের আছে -

# Inputs : arr, ind, axis
idx = np.ogrid[tuple(map(slice, ind.shape))]
idx[axis] = ind
out = arr[tuple(idx)]

কেবল এটিকে কার্যক্ষম করতে এবং ত্রুটি পরীক্ষা করতে, আসুন দুটি ফাংশন তৈরি করা যাক - একটি সেই সূচকগুলি পাওয়া এবং দ্বিতীয়টি ডেটা অ্যারেতে এবং কেবল সূচকগুলিতে ফিড করা। প্রথম ফাংশনটির সাথে ধারণাটি হ'ল সূচকগুলি যে কোনও স্বেচ্ছাসেবী অ্যারেতে ইনডেক্সিংয়ের জন্য পুনরায় ব্যবহার করা যেতে পারে যা প্রতিটি অক্ষ বরাবর প্রয়োজনীয় সংখ্যা এবং দৈর্ঘ্যের সমর্থন করবে support

সুতরাং, বাস্তবায়ন হবে -

def advindex_allaxes(ind, axis):
    axis = np.core.multiarray.normalize_axis_index(axis,ind.ndim)
    idx = np.ogrid[tuple(map(slice, ind.shape))]
    idx[axis] = ind
    return tuple(idx)

def take_along_axis(arr, ind, axis):
    return arr[advindex_allaxes(ind, axis)]

নমুনা রান -

In [161]: A = np.array([[3,2,1],[4,0,6]])

In [162]: B = np.array([[3,1,4],[1,5,9]])

In [163]: i = A.argsort(axis=-1)

In [164]: take_along_axis(A,i,axis=-1)
Out[164]: 
array([[1, 2, 3],
       [0, 4, 6]])

In [165]: take_along_axis(B,i,axis=-1)
Out[165]: 
array([[4, 1, 3],
       [5, 1, 9]])

Relevant one


এই আরগসোর্টটি একটি (3,2) অ্যারে তৈরি করে

In [453]: idx=np.argsort(A,axis=-1)
In [454]: idx
Out[454]: 
array([[0, 1],
       [1, 0],
       [0, 1]], dtype=int32)

যেমনটি আপনি np.sort(A, axis=-1) সমমান np.sort(A, axis=-1) পাওয়ার জন্য এটি A প্রয়োগ করার বিষয়টি np.sort(A, axis=-1) isn't পুনরাবৃত্ত সমাধানটি প্রতিটি সারি (1 ডি কেস) এর সাথে সাজান:

In [459]: np.array([x[i] for i,x in zip(idx,A)])
Out[459]: 
array([[-1.0856306 ,  0.99734545],
       [-1.50629471,  0.2829785 ],
       [-0.57860025,  1.65143654]])

সম্ভবত দ্রুততম না হলেও এটি সম্ভবত সবচেয়ে পরিষ্কার সমাধান এবং আরও ভাল সমাধানকে ধারণার জন্য একটি ভাল সূচনার পয়েন্ট।

take সলিউশন থেকে tuple(inds) হ'ল:

(array([[0],
        [1],
        [2]]), 
 array([[0, 1],
        [1, 0],
        [0, 1]], dtype=int32))
In [470]: A[_]
Out[470]: 
array([[-1.0856306 ,  0.99734545],
       [-1.50629471,  0.2829785 ],
       [-0.57860025,  1.65143654]])

অন্য কথায়:

In [472]: A[np.arange(3)[:,None], idx]
Out[472]: 
array([[-1.0856306 ,  0.99734545],
       [-1.50629471,  0.2829785 ],
       [-0.57860025,  1.65143654]])

প্রথম অংশটি হল np.ix_ যা np.ix_ করবে তবে এটি 2 ডি idx 'পছন্দ' করে না।

দেখে মনে হচ্ছে কয়েক বছর আগে আমি এই বিষয়টিকে ঘুরে দেখলাম

একটি বহুমাত্রিক নাদারের জন্য আর্গোর্ট

a[np.arange(np.shape(a)[0])[:,np.newaxis], np.argsort(a)]

আমি কী চলছে তা বোঝানোর চেষ্টা করেছি। take ফাংশনটি একই ধরণের কাজ করে তবে আরও সাধারণ কেস (মাত্রা এবং অক্ষ) এর জন্য সূচী টিপলটি তৈরি করে। আরও মাত্রায় সাধারণীকরণ করা, তবে axis=-1 সহজ হওয়া উচিত।

প্রথম অক্ষের জন্য, A[np.argsort(A,axis=0),np.arange(2)] কাজ করে।






numpy