একটি NumPy বহুমাত্রিক অ্যারের আইথ কলামটি কীভাবে অ্যাক্সেস করবেন?


461

ধরুন আমার আছে:

test = numpy.array([[1, 2], [3, 4], [5, 6]])

test[i]আমাকে অ্যারের ith লাইন পায় (যেমন [1, 2])। আমি কীভাবে আইথ কলামটি অ্যাক্সেস করতে পারি ? (যেমন [1, 3, 5]) এছাড়াও, এটি একটি ব্যয়বহুল অপারেশন হবে?

উত্তর:


684
>>> test[:,0]
array([1, 3, 5])

একইভাবে,

>>> test[1,:]
array([3, 4])

আপনাকে সারি অ্যাক্সেস করতে দেয়। এটি নম্পপি রেফারেন্সের বিভাগ 1.4 (সূচীকরণ) এ আচ্ছাদিত । কমপক্ষে আমার অভিজ্ঞতায় এটি দ্রুত। এটি অবশ্যই লুপের প্রতিটি উপাদান অ্যাক্সেস করার চেয়ে অনেক দ্রুত।


11
এটি একটি অনুলিপি তৈরি করে রেফারেন্স পাওয়া কি সম্ভব, যেমন আমি কোনও কলামে একটি রেফারেন্স পাই, এই রেফারেন্সের কোনও পরিবর্তন মূল অ্যারেতে প্রতিফলিত হয়।
18:21

@harmands এটি একটি অনুলিপি তৈরি করে না, এটি একটি ভিউ তৈরি করে।
rinspy

69

এবং আপনি যদি একবারে একাধিক কলাম অ্যাক্সেস করতে চান তবে আপনি করতে পারেন:

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

যদিও অবশ্যই এই ক্ষেত্রে আপনি কেবল ডেটা অ্যাক্সেস করছেন না ; আপনি একটি অনুলিপি ফিরিয়ে দিচ্ছেন (অভিনব সূচক)
জন গ্রিনাল

14
test[:,[0,2]]কেবলমাত্র ডেটা অ্যাক্সেস করে, উদাহরণস্বরূপ, test[:, [0,2]] = somethingপরীক্ষাটি সংশোধন করবে, এবং অন্য অ্যারে তৈরি করবে না। কিন্তু copy_test = test[:, [0,2]]বাস্তবে আপনি যেমন বলছেন তেমন একটি অনুলিপি তৈরি করে।
আকাওয়াল

3
এটি একটি অনুলিপি তৈরি করে, আমি কি কিছু কলামের রেফারেন্স পেয়েছি, যেমন রেফারেন্স পাওয়া সম্ভব, এই রেফারেন্সের কোনও পরিবর্তন আসল অ্যারেতে প্রতিফলিত হয়?
18:25

@ harman786 আপনি কেবল পুরানোটির কাছে পরিবর্তিত অ্যারেটিকে পুনরায় নিয়োগ করতে পারেন।
তমোঘনা চৌধুরী

কেন না test[:,[0,2]]কেবল ডাটা অ্যাক্সেস করে test[:, [0, 2]][:, [0, 1]]? এটি অত্যন্ত অনিচ্ছাকৃত বলে মনে হয় যে একই জিনিসটি আবার করা একটি পৃথক ফলাফল রয়েছে।
mapf

65
>>> test[:,0]
array([1, 3, 5])

এই কমান্ডটি আপনাকে একটি সারি ভেক্টর সরবরাহ করে, যদি আপনি কেবল এটির উপর লুপ করতে চান তবে এটি ঠিক আছে, তবে আপনি যদি 3xNN মাত্রার সাথে অন্য কোনও অ্যারের সাথে hstack করতে চান তবে আপনি পাবেন

ValueError: all the input arrays must have same number of dimensions

যখন

>>> test[:,[0]]
array([[1],
       [3],
       [5]])

আপনাকে একটি কলাম ভেক্টর দেয়, যাতে আপনি সংমিশ্রিত বা hstack অপারেশন করতে পারেন।

যেমন

>>> np.hstack((test, test[:,[0]]))
array([[1, 2, 1],
       [3, 4, 3],
       [5, 6, 5]])

1
সূচীকরণ একবারে কলামেরও বেশি কাজ করে, তাই সর্বশেষ উদাহরণটি পরীক্ষা [:, [0,1,0]] বা পরীক্ষা হতে পারে [:, [পরিসীমা (টেস্ট.শ্যাপ [1]) + [0]] ]
lib

5
সারি ভেক্টরের পরিবর্তে কলাম ভেক্টর পেতে [:, [0]] বনাম [:, 0] নির্দিষ্ট করার জন্য +1। ঠিক আমি যে আচরণটি খুঁজছিলাম। অতিরিক্ত ইনডেক্সিং নোটের জন্যও +1 করুন। এই উত্তরটি শীর্ষ উত্তর সহ ঠিক সেখানে হওয়া উচিত।
dhj

1
এই উত্তরটি অবশ্যই চয়ন করা উচিত
গুসেভ স্লাভা

22

আপনি স্থানান্তর করতে এবং একটি সারিও ফিরিয়ে দিতে পারেন:

In [4]: test.T[0]
Out[4]: array([1, 3, 5])

আমি কলামগুলি অ্যাক্সেস করার দ্রুততম উপায় সন্ধান করার আগে কিছুক্ষণের জন্য এটি করছি, আমি আশ্চর্য হই যে এটি কি দ্রুত, ধীর বা পরীক্ষার মতোই [], [0]]
জোসে চামেরো


5

যদিও প্রশ্নের উত্তর দেওয়া হয়েছে, তবে কিছু সংক্ষিপ্তসার উল্লেখ করি।

ধরা যাক আপনি অ্যারের প্রথম কলামে আগ্রহী

arr = numpy.array([[1, 2],
                   [3, 4],
                   [5, 6]])

আপনি অন্যান্য উত্তর থেকে ইতিমধ্যে জানেন যে, এটি "সারি ভেক্টর" (আকৃতির অ্যারে (3,)) আকারে পেতে , আপনি কাটা ব্যবহার করেন:

arr_c1_ref = arr[:, 1]  # creates a reference to the 1st column of the arr
arr_c1_copy = arr[:, 1].copy()  # creates a copy of the 1st column of the arr

অ্যারেটি একটি ভিউ বা অন্য অ্যারের অনুলিপি কিনা তা যাচাই করতে আপনি নিম্নলিখিতটি করতে পারেন:

arr_c1_ref.base is arr  # True
arr_c1_copy.base is arr  # False

দেখতে ndarray.base

উভয়ের মধ্যে সুস্পষ্ট পার্থক্য ছাড়াও (পরিবর্তিতকরণ arr_c1_refপ্রভাবিত করবে arr), তাদের প্রত্যেককে অনুসরণ করার জন্য বাই-পদক্ষেপের সংখ্যা পৃথক:

arr_c1_ref.strides[0]  # 8 bytes
arr_c1_copy.strides[0]  # 4 bytes

দেখতে পদক্ষেপ । ইহা কেন গুরুত্বপূর্ণ? কল্পনা করুন যে এর Aপরিবর্তে আপনার খুব বড় অ্যারে রয়েছে arr:

A = np.random.randint(2, size=(10000,10000), dtype='int32')
A_c1_ref = A[:, 1] 
A_c1_copy = A[:, 1].copy()

এবং আপনি প্রথম কলামের সমস্ত উপাদানের যোগফল গণনা করতে চান, A_c1_ref.sum()বা A_c1_copy.sum()। অনুলিপি করা সংস্করণটি ব্যবহার করা আরও দ্রুত:

%timeit A_c1_ref.sum()  # ~248 µs
%timeit A_c1_copy.sum()  # ~12.8 µs

এটি পূর্বে উল্লিখিত বিভিন্ন ধাপের কারণে is

A_c1_ref.strides[0]  # 40000 bytes
A_c1_copy.strides[0]  # 4 bytes

যদিও এটি মনে হতে পারে যে কলাম অনুলিপিগুলি ব্যবহার করা আরও ভাল, কারণ অনুলিপি তৈরি করতে সময় লাগে এবং আরও স্মৃতি ব্যবহার হয় (এই ক্ষেত্রে এটি তৈরি করতে আমার প্রায় 200 ডলার লাগিয়েছিল A_c1_copy) কারণটি সত্য নয় । তবে যদি প্রথমে আমাদের অনুলিপিটির প্রয়োজন হয়, বা অ্যারের নির্দিষ্ট কলামে আমাদের অনেকগুলি বিভিন্ন ক্রিয়াকলাপ করা দরকার এবং আমরা গতির জন্য স্মৃতি ত্যাগ করতে ঠিক আছি, তবে অনুলিপি তৈরির উপায় the

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

A = np.asfortranarray(A)  # or np.array(A, order='F')
A_c1_ref = A[:, 1]
A_c1_ref.strides[0]  # 4 bytes
%timeit A_c1_ref.sum()  # ~12.6 µs vs ~248 µs

এখন, একটি কলাম ভিউতে যোগ ক্রিয়া (বা অন্য কোনও) সম্পাদন করা আরও দ্রুত much

পরিশেষে আমি নোট করি যে একটি অ্যারে স্থানান্তরিত করা এবং সারি-স্লাইসিং ব্যবহার করা মূল অ্যারেটিতে কলাম-স্লাইসিংয়ের ব্যবহার সমান, কারণ ট্রান্সপোসিংটি কেবল মূল অ্যারের আকার এবং অদলবদল অদলবদল করে।

A.T[1,:].strides[0]  # 40000

3
>>> test
array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])

>>> ncol = test.shape[1]
>>> ncol
5L

তারপরে আপনি এইভাবে দ্বিতীয় - চতুর্থ কলামটি নির্বাচন করতে পারেন:

>>> test[0:, 1:(ncol - 1)]
array([[1, 2, 3],
       [6, 7, 8]])
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.