NumPy ইনডেক্সের তালিকা ব্যবহার করে প্রতি সারিতে নির্দিষ্ট কলাম সূচক নির্বাচন করে


90

আমি NumPyম্যাট্রিক্সের প্রতি সারি নির্দিষ্ট কলামগুলি নির্বাচন করতে লড়াই করছি ।

ধরুন আমার কাছে নিম্নলিখিত ম্যাট্রিক্স রয়েছে যা আমি কল করব X:

[1, 2, 3]
[4, 5, 6]
[7, 8, 9]

আমার কাছে listপ্রতি সারিতে কলাম সূচীর একটিও রয়েছে যা আমি কল করব Y:

[1, 0, 2]

আমার মানগুলি পাওয়া দরকার:

[2]
[4]
[9]

পরিবর্তে একটি এর listইনডেক্স সঙ্গে Yআমিও হিসাবে একই আকৃতি সঙ্গে একটি ম্যাট্রিক্স তৈরী করতে পারে Xযেখানে প্রত্যেক কলামটি একটি হল bool/ intপরিসীমা 0-1 মান, যা নির্দেশ কিনা এই প্রয়োজনীয় কলাম হয়।

[0, 1, 0]
[1, 0, 0]
[0, 0, 1]

আমি জানি এটি অ্যারের মাধ্যমে পুনরাবৃত্তি এবং আমার প্রয়োজনীয় কলাম মানগুলি নির্বাচন করে করা যেতে পারে। যাইহোক, এটি ডেটার বড় অ্যারেগুলিতে ঘন ঘন মৃত্যুদন্ড কার্যকর করা হবে এবং এজন্য এটি যত তাড়াতাড়ি চালাতে হবে।

আমি এইভাবে ভাবছিলাম যে এর থেকে আরও ভাল সমাধান আছে কিনা?

ধন্যবাদ.


উত্তরটি কি আপনার পক্ষে ভাল? stackoverflow.com/a/17081678/5046896
GoingMyWay

উত্তর:


102

যদি আপনি বুলিয়ান অ্যারে পেয়ে থাকেন তবে আপনি এর মতো ভিত্তিতে সরাসরি নির্বাচন করতে পারেন:

>>> a = np.array([True, True, True, False, False])
>>> b = np.array([1,2,3,4,5])
>>> b[a]
array([1, 2, 3])

আপনার প্রাথমিক উদাহরণটি অনুসরণ করতে আপনি নিম্নলিখিতগুলি করতে পারেন:

>>> a = np.array([[1,2,3], [4,5,6], [7,8,9]])
>>> b = np.array([[False,True,False],[True,False,False],[False,False,True]])
>>> a[b]
array([2, 4, 9])

আপনি arangeকীভাবে আপনার বুলিয়ান অ্যারে তৈরি করছেন এবং আপনার কোডটি ওয়াইএমএমভি দেখতে কেমন দেখাচ্ছে তার উপর নির্ভর করে আপনি এটিতে যুক্ত করতে এবং এতে সরাসরি নির্বাচন করতে পারেন।

>>> a = np.array([[1,2,3], [4,5,6], [7,8,9]])
>>> a[np.arange(len(a)), [1,0,2]]
array([2, 4, 9])

আশা করি এটি সহায়তা করে, আপনার যদি আরও কোনও প্রশ্ন থাকে তবে আমাকে জানান।


11
উদাহরণস্বরূপ ব্যবহারের জন্য +1 arange। একাধিক ম্যাট্রিক থেকে বিভিন্ন ব্লক পুনরুদ্ধারের জন্য এটি আমার জন্য বিশেষভাবে কার্যকর ছিল (সুতরাং মূলত এই উদাহরণের 3 ডি কেস)
গ্রিডো

4
হাই, আপনি কেন আমাদের arangeপরিবর্তে ব্যবহার করতে হবে তা ব্যাখ্যা করতে পারেন :? আমি জানি যে আপনার উপায় কাজ করে এবং আমার কাজ করে না তবে আমি কেন এটি বুঝতে চাই।
মার্কোতমা

@ ট্যামজার্ড কারণ এটি একটি অদ্ভুত অ্যারে এবং ভ্যানিলা পাইথন তালিকা নয়, তাই :সিনট্যাক্স একইভাবে কাজ করে না।
স্লেটার ভিক্টোরফ

4
@ স্লেটারটাইরানস, সাড়া দেওয়ার জন্য ধন্যবাদ। কিছুটা পড়ার পরে আমার বোঝাপড়াটি হ'ল :উন্নত ইনডেক্সিংয়ের সাথে মিশ্রণের অর্থ: "প্রতিটি উপ-স্থানের পাশাপাশি :প্রদত্ত অগ্রণী সূচকটি প্রয়োগ করুন"। আমার বোধগম্যতা কি সঠিক?
মার্কোতমা

@ ট্যামজার্ড "সাব-স্পেস" বলতে আপনার অর্থটি ব্যাখ্যা করুন
স্লেটার ভিক্টোরফ

35

আপনি এর মতো কিছু করতে পারেন:

In [7]: a = np.array([[1, 2, 3],
   ...: [4, 5, 6],
   ...: [7, 8, 9]])

In [8]: lst = [1, 0, 2]

In [9]: a[np.arange(len(a)), lst]
Out[9]: array([2, 4, 9])

আরো বহু মাত্রিক অ্যারে সূচিবদ্ধ করুন: http://docs.scipy.org/doc/numpy/user/basics.indexing.html#indexing-multi-dimensional-arrays


4
কেবল ':' বা ব্যাপ্তির পরিবর্তে অ্যারেঞ্জ কেন দরকার তা বোঝার জন্য সংগ্রাম ling
ম্যাডম্যানলি

@ ম্যাডম্যানলি হাই, ফলাফলগুলির :একাধিকবার আউটপুট দেবে len(a), পরিবর্তে, প্রতিটি সারির সূচকটি প্রত্যাশিত ফলাফল মুদ্রণ করবে।
GoingMyWay

4
আমি মনে করি এটি হ'ল এই সমস্যাটি সমাধান করার সঠিক এবং মার্জিত উপায়।
GoingMyWay

6

একটি সহজ উপায় হতে পারে:

In [1]: a = np.array([[1, 2, 3],
   ...: [4, 5, 6],
   ...: [7, 8, 9]])

In [2]: y = [1, 0, 2]  #list of indices we want to select from matrix 'a'

range(a.shape[0]) ফিরে আসবে array([0, 1, 2])

In [3]: a[range(a.shape[0]), y] #we're selecting y indices from every row
Out[3]: array([2, 4, 9])

4
দয়া করে ব্যাখ্যাগুলি বিবেচনা করুন।
souki

@ সউকি আমি এখন ব্যাখ্যা যোগ করেছি। ধন্যবাদ
ধাওয়াল মায়াত্রা

6

সাম্প্রতিক numpyসংস্করণগুলি এমন একটি take_along_axis(এবং put_along_axis) যুক্ত করেছে যা পরিষ্কারভাবে এই সূচকটি করে।

In [101]: a = np.arange(1,10).reshape(3,3)                                                             
In [102]: b = np.array([1,0,2])                                                                        
In [103]: np.take_along_axis(a, b[:,None], axis=1)                                                     
Out[103]: 
array([[2],
       [4],
       [9]])

এটি একইভাবে কাজ করে:

In [104]: a[np.arange(3), b]                                                                           
Out[104]: array([2, 4, 9])

তবে বিভিন্ন অক্ষ পরিচালনা করে। এটা বিশেষ করে ফলাফল প্রয়োগের লক্ষ্যে এর argsortএবং argmax


3

আপনি এটির ব্যবহার করে এটি করতে পারেন। এটার মত:

np.fromiter((row[index] for row, index in zip(X, Y)), dtype=int)

সময়:

N = 1000
X = np.zeros(shape=(N, N))
Y = np.arange(N)

#@Aशwini चhaudhary
%timeit X[np.arange(len(X)), Y]
10000 loops, best of 3: 30.7 us per loop

#mine
%timeit np.fromiter((row[index] for row, index in zip(X, Y)), dtype=int)
1000 loops, best of 3: 1.15 ms per loop

#mine
%timeit np.diag(X.T[Y])
10 loops, best of 3: 20.8 ms per loop

4
ওপি উল্লেখ করেছে যে এটি বড় অ্যারেগুলিতে দ্রুত চালানো উচিত , তাই আপনার মানদণ্ড খুব প্রতিনিধিত্বমূলক নয়। আমি জানতে আগ্রহী যে আপনার শেষ পদ্ধতিটি বৃহত্তর অ্যারেগুলির জন্য কীভাবে সম্পাদন করে!

টুইটারে np.diag(X.T[Y])খুব ধীর ... তবে np.diag(X.T)খুব দ্রুত (10us)। কেন জানি না।
কেই মিনাগাওয়া

0

আর একটি চৌকস উপায় হ'ল প্রথমে অ্যারে স্থানান্তর করা এবং তারপরে এটি সূচীকরণ করা। শেষ পর্যন্ত, তির্যক নিন, এটি সর্বদা সঠিক উত্তর।

X = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
Y = np.array([1, 0, 2, 2])

np.diag(X.T[Y])

ধাপে ধাপে:

আসল অ্যারে:

>>> X
array([[ 1,  2,  3],
       [ 4,  5,  6],
       [ 7,  8,  9],
       [10, 11, 12]])

>>> Y
array([1, 0, 2, 2])

এটি সঠিকভাবে সূচী করা সম্ভব করতে ট্রান্সপোজ করুন।

>>> X.T
array([[ 1,  4,  7, 10],
       [ 2,  5,  8, 11],
       [ 3,  6,  9, 12]])

Y ক্রমে সারি পান।

>>> X.T[Y]
array([[ 2,  5,  8, 11],
       [ 1,  4,  7, 10],
       [ 3,  6,  9, 12],
       [ 3,  6,  9, 12]])

তির্যকটি এখন পরিষ্কার হওয়া উচিত।

>>> np.diag(X.T[Y])
array([ 2,  4,  9, 12]

4
এই প্রযুক্তিগতভাবে কাজ করে এবং খুব মার্জিত দেখায়। তবে, আমি দেখতে পাচ্ছি যে আপনি যখন বড় অ্যারে ব্যবহার করছেন তখন এই পদ্ধতিটি পুরোপুরি বিস্ফোরিত হয়। আমার ক্ষেত্রে, নুমপি 30 জিবি সোয়াপ গিলে ফেলেছে এবং আমার এসএসডি পূরণ করেছে। আমি পরিবর্তে অগ্রণী সূচক পদ্ধতির ব্যবহার করার পরামর্শ দিই।
5nefarious
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.