2 ডি অ্যারে তৃতীয় মাত্রায়, অন বারে অনুলিপি করুন (পাইথন)


118

আমি একটি ন্যাকপি 2 ডি অ্যারেটিকে তৃতীয় মাত্রায় অনুলিপি করতে চাই। উদাহরণস্বরূপ, (2D) নাম্বার অ্যারে দেওয়া:

import numpy as np
arr = np.array([[1,2],[1,2]])
# arr.shape = (2, 2)

এটিকে একটি নতুন মাত্রায় এন এর মতো অনুলিপিগুলির সাথে একটি 3D ম্যাট্রিক্সে রূপান্তর করুন। arrএন = 3 দিয়ে অভিনয় করে আউটপুটটি হওয়া উচিত:

new_arr = np.array([[[1,2],[1,2]],[[1,2],[1,2]],[[1,2],[1,2]]])
# new_arr.shape = (3, 2, 2)

উত্তর:


158

সম্ভবত সবচেয়ে পরিষ্কার উপায়টি হ'ল np.repeat:

a = np.array([[1, 2], [1, 2]])
print(a.shape)
# (2,  2)

# indexing with np.newaxis inserts a new 3rd dimension, which we then repeat the
# array along, (you can achieve the same effect by indexing with None, see below)
b = np.repeat(a[:, :, np.newaxis], 3, axis=2)

print(b.shape)
# (2, 2, 3)

print(b[:, :, 0])
# [[1 2]
#  [1 2]]

print(b[:, :, 1])
# [[1 2]
#  [1 2]]

print(b[:, :, 2])
# [[1 2]
#  [1 2]]

এটি বলার পরে, আপনি প্রায়শই সম্প্রচার ব্যবহার করে আপনার অ্যারেগুলি পুরোপুরি পুনরাবৃত্তি করা এড়াতে পারেন । উদাহরণস্বরূপ, ধরা যাক আমি একটি (3,)ভেক্টর যুক্ত করতে চেয়েছিলাম :

c = np.array([1, 2, 3])

to a। আমি aতৃতীয় মাত্রায় 3 বারের বিষয়বস্তু অনুলিপি করতে পারি , তারপরে cপ্রথম এবং দ্বিতীয় উভয় মাত্রায় দু'বার কন্টেন্টটি অনুলিপি করতে পারি , যাতে আমার উভয় অ্যারে হয় (2, 2, 3), তারপরে তাদের যোগফল গণনা করুন। তবে এটি করা খুব সহজ এবং দ্রুত:

d = a[..., None] + c[None, None, :]

এখানে, a[..., None]আকৃতি আছে (2, 2, 1)এবং c[None, None, :]আকৃতি আছে (1, 1, 3)*। আমি যখন যোগফলটি গণনা করি তখন ফলাফলটি 1 মাপের আকারের সাথে 'সম্প্রচারিত' হয়ে যায়, যা আমাকে আকৃতির ফলাফল দেয় (2, 2, 3):

print(d.shape)
# (2,  2, 3)

print(d[..., 0])    # a + c[0]
# [[2 3]
#  [2 3]]

print(d[..., 1])    # a + c[1]
# [[3 4]
#  [3 4]]

print(d[..., 2])    # a + c[2]
# [[4 5]
#  [4 5]]

সম্প্রচার হ'ল একটি শক্তিশালী কৌশল কারণ এটি স্মরণে আপনার ইনপুট অ্যারের বারবার অনুলিপি তৈরিতে জড়িত অতিরিক্ত ওভারহেডকে এড়িয়ে চলে।


* যদিও আমি সেগুলি স্পষ্টতার জন্য অন্তর্ভুক্ত করেছি, তবে Noneসূচকগুলি cআসলে প্রয়োজনীয় নয় - আপনি এটি করতেও পারেন a[..., None] + c, অর্থাত্ (2, 2, 1)অ্যারের বিরুদ্ধে অ্যারে সম্প্রচার করে (3,)। এটি কারণ যদি অ্যারেগুলির মধ্যে একটির অপরটির চেয়ে কম মাত্রা থাকে তবে কেবলমাত্র দুটি অ্যারেটির অনুবর্তনীয় মাত্রাগুলি সামঞ্জস্যপূর্ণ হওয়া দরকার। আরও জটিল উদাহরণ দিতে:

a = np.ones((6, 1, 4, 3, 1))  # 6 x 1 x 4 x 3 x 1
b = np.ones((5, 1, 3, 2))     #     5 x 1 x 3 x 2
result = a + b                # 6 x 5 x 4 x 3 x 2

য়ে ইনি সত্যিই সঠিক ফলাফল দেয় যাচাই করতে, আপনার কাছে প্রিন্ট আউট করতে পারেন b[:,:,0], b[:,:,1]এবং b[:,:,2]। প্রতিটি তৃতীয় মাত্রার স্লাইসটি মূল 2D অ্যারের অনুলিপি। এটি কেবল তাকানো হিসাবে সুস্পষ্ট নয় print(b)
ইলে

কোনটিই নয় এবং এনপি.নেউক্সিসের মধ্যে পার্থক্য কী? যখন আমি এটি পরীক্ষা করেছি, এটি একই ফলাফল দিয়েছে।
একবিন্দু

4
@ ওয়েডরান তারা হুবহু np.newaxisহ'লNone
আলি_মি

28

অন্য উপায় ব্যবহার করা হয় numpy.dstack। মনে করুন আপনি ম্যাট্রিক্স a num_repeatsবার পুনরাবৃত্তি করতে চান :

import numpy as np
b = np.dstack([a]*num_repeats)

কৌশলটি হ'ল ম্যাট্রিক্সকে aএকটি একক উপাদানের তালিকায় আবৃত করা, তারপরে *অপারেটরটি ব্যবহার করে এই তালিকা num_repeatsবারের উপাদানগুলি নকল করতে ।

উদাহরণস্বরূপ, যদি:

a = np.array([[1, 2], [1, 2]])
num_repeats = 5

এটি [1 2; 1 2]তৃতীয় মাত্রায় 5 বার অ্যারের পুনরাবৃত্তি করে । যাচাই করতে (আইপিথনে):

In [110]: import numpy as np

In [111]: num_repeats = 5

In [112]: a = np.array([[1, 2], [1, 2]])

In [113]: b = np.dstack([a]*num_repeats)

In [114]: b[:,:,0]
Out[114]: 
array([[1, 2],
       [1, 2]])

In [115]: b[:,:,1]
Out[115]: 
array([[1, 2],
       [1, 2]])

In [116]: b[:,:,2]
Out[116]: 
array([[1, 2],
       [1, 2]])

In [117]: b[:,:,3]
Out[117]: 
array([[1, 2],
       [1, 2]])

In [118]: b[:,:,4]
Out[118]: 
array([[1, 2],
       [1, 2]])

In [119]: b.shape
Out[119]: (2, 2, 5)

শেষে আমরা দেখতে পাচ্ছি ম্যাট্রিক্সের আকারটি 2 x 2তৃতীয় মাত্রায় 5 টি স্লাইস রয়েছে।


এর সাথে কীভাবে তুলনা করা যায় reshape? আরও দ্রুত? একই কাঠামো দেয়? এটি অবশ্যই আরও সুন্দর
আন্ডার বিগুড়ি

@ আন্ডারবিগুড়ি আমি কখনও বেঞ্চমার্ক করিনি ... আমি এখানে প্রাথমিকভাবে সম্পূর্ণতার জন্য রেখেছি। এটি সময় আকর্ষণীয় এবং পার্থক্যগুলি দেখতে পাবেন।
রায়রেং

4
আমি সবে img = np.dstack ([আরআর] * 3) করেছি এবং ভাল কাজ করেছি! আপনাকে ধন্যবাদ
Thanos.a

4
অঙ্কিত আমি দক্ষতার জন্য একটি দেখা আউটপুট প্রস্তাব করতে পারে। একটি পুরানো পোস্ট হওয়ায় লোকেরা সেটিকে মিস করতে পারে। এই প্রশ্নোত্তর উপর একটি সমাধান যুক্ত করা হয়েছে।
দিবাকর

4
আইএমএইচও সবচেয়ে পঠনযোগ্য সমাধান, তবে তুলনার জন্য অন্যান্য পদ্ধতির তুলনায় এটি বেঞ্চমার্ক করা দুর্দান্ত।
mrgloom

22

একটি দর্শন ব্যবহার করুন এবং বিনামূল্যে রানটাইম পান! জেনেরিক n-dimঅ্যারে প্রসারিত করুনn+1-dim

চালু NumPy1.10.0 , আমরা লিভারেজ করতে numpy.broadcast_toকেবল একটি জেনারেট করতে 3Dমধ্যে দৃশ্য 2Dইনপুট অ্যারের। সুবিধাটি কোনও অতিরিক্ত মেমরি ওভারহেড এবং কার্যত ফ্রি রানটাইম হবে না। অ্যারেগুলি বড় হয় এবং আমরা মতামত নিয়ে কাজ করতে ঠিক আছি এমন ক্ষেত্রে এটি প্রয়োজনীয়। এছাড়াও, এটি জেনেরিক কেসগুলির সাথে কাজ করবে n-dim

আমি শব্দটি তার stackজায়গায় ব্যবহার করবো copy, কারণ পাঠকরা এটিকে অ্যারে অনুলিপি করে যা মেমরির অনুলিপি তৈরি করে তা নিয়ে বিভ্রান্ত করতে পারে।

প্রথম অক্ষ বরাবর স্ট্যাক

আমরা যদি arrপ্রথম অক্ষ বরাবর ইনপুট স্ট্যাক করতে চাই তবে ভিউ np.broadcast_toতৈরির সমাধানটি হ'ল 3D-

np.broadcast_to(arr,(3,)+arr.shape) # N = 3 here

তৃতীয় / শেষ অক্ষ বরাবর স্ট্যাক

arrতৃতীয় অক্ষ বরাবর ইনপুট স্ট্যাক করার জন্য, 3Dভিউ তৈরির সমাধানটি হ'ল -

np.broadcast_to(arr[...,None],arr.shape+(3,))

আমাদের যদি আসলে মেমরির অনুলিপি প্রয়োজন হয় তবে আমরা সর্বদা .copy()সেখানে যুক্ত করতে পারি । সুতরাং, সমাধানগুলি হবে -

np.broadcast_to(arr,(3,)+arr.shape).copy()
np.broadcast_to(arr[...,None],arr.shape+(3,)).copy()

একটি নমুনা কেসগুলির জন্য তাদের আকারের তথ্যের সাথে দেখানো স্ট্যাকিং কীভাবে দুটি ক্ষেত্রে কাজ করে -

# Create a sample input array of shape (4,5)
In [55]: arr = np.random.rand(4,5)

# Stack along first axis
In [56]: np.broadcast_to(arr,(3,)+arr.shape).shape
Out[56]: (3, 4, 5)

# Stack along third axis
In [57]: np.broadcast_to(arr[...,None],arr.shape+(3,)).shape
Out[57]: (4, 5, 3)

একই সমাধান (গুলি) প্রথম এবং শেষ অক্ষ সহ আউটপুট দেখতে একটি n-dimইনপুট প্রসারিত করতে কাজ করবে n+1-dim। আসুন কিছু উচ্চতর ম্লান কেস অনুসন্ধান করুন -

3 ডি ইনপুট কেস:

In [58]: arr = np.random.rand(4,5,6)

# Stack along first axis
In [59]: np.broadcast_to(arr,(3,)+arr.shape).shape
Out[59]: (3, 4, 5, 6)

# Stack along last axis
In [60]: np.broadcast_to(arr[...,None],arr.shape+(3,)).shape
Out[60]: (4, 5, 6, 3)

4D ইনপুট কেস:

In [61]: arr = np.random.rand(4,5,6,7)

# Stack along first axis
In [62]: np.broadcast_to(arr,(3,)+arr.shape).shape
Out[62]: (3, 4, 5, 6, 7)

# Stack along last axis
In [63]: np.broadcast_to(arr[...,None],arr.shape+(3,)).shape
Out[63]: (4, 5, 6, 7, 3)

ইত্যাদি।

সময়

আসুন একটি বৃহত নমুনা 2Dকেস ব্যবহার করুন এবং সময়গুলি পান এবং আউটপুটটি যাচাই করি view

# Sample input array
In [19]: arr = np.random.rand(1000,1000)

আসুন প্রমাণ করুন যে প্রস্তাবিত সমাধানটি সত্যই একটি দৃষ্টিভঙ্গি। আমরা প্রথম অক্ষ বরাবর স্ট্যাকিং ব্যবহার করব (তৃতীয় অক্ষ বরাবর স্ট্যাকিংয়ের জন্য ফলাফলগুলি একই রকম হবে) -

In [22]: np.shares_memory(arr, np.broadcast_to(arr,(3,)+arr.shape))
Out[22]: True

এটি কার্যত নিখরচায় প্রদর্শনের সময়গুলি পান -

In [20]: %timeit np.broadcast_to(arr,(3,)+arr.shape)
100000 loops, best of 3: 3.56 µs per loop

In [21]: %timeit np.broadcast_to(arr,(3000,)+arr.shape)
100000 loops, best of 3: 3.51 µs per loop

, একটি দৃশ্য হচ্ছে বৃদ্ধি Nথেকে 3থেকে 3000সময় পরিবর্তন কিছুই এবং উভয় সময়জ্ঞান ইউনিটে তুচ্ছ হয়। অতএব, স্মৃতি এবং কর্মক্ষমতা উভয় দক্ষ!


3
A=np.array([[1,2],[3,4]])
B=np.asarray([A]*N)

মাত্রা ক্রম সংরক্ষণ করতে @ মিঃএফএফ সম্পাদনা করুন:

B=B.T

এটি আমার জন্য একটি এন এক্স 2 এক্স 2 অ্যারে ফলাফল করে, উদাহরণস্বরূপ যেকোন মানের জন্য B.shapeপ্রিন্ট করে । আপনি যদি সাথে স্থানান্তর করেন তবে এটি প্রত্যাশিত আউটপুটটির সাথে মিলে যায়। (N, 2, 2)NBB.T
ইলিশ

@ মিঃ এফ - আপনি সঠিক বলেছেন। এই প্রথম মাত্রা বরাবর সম্প্রচার হবে, এবং তা করার B[0], B[1],...ডান ফালি, যা আমি তর্ক করব দেব এবং যে এর আরো সহজ বদলে টাইপ ব্যবহার বলছি B[:,:,0], B[:,:,1], ইত্যাদি
rayryeng

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

@ মিঃ এফ - ওহ অবশ্যই ভবিষ্যতে আপনি কী অ্যাপ্লিকেশনগুলি 3 ডি ম্যাট্রিক্স ব্যবহার করতে চাইবেন তা অনুমান করতে পারি না। বলা হচ্ছে, এটি সমস্ত প্রয়োগের উপর নির্ভর করে। এফডাব্লুআইডাব্লু, আমি B[:,:,i]পাশাপাশি পছন্দ করি যা আমি অভ্যস্ত।
রাইরিং


2

এখানে একটি সম্প্রচার উদাহরণ যা অনুরোধ করা হয়েছিল ঠিক তাই করে।

a = np.array([[1, 2], [1, 2]])
a=a[:,:,None]
b=np.array([1]*5)[None,None,:]

তারপরে b*aকাঙ্ক্ষিত ফলাফল এবং (b*a)[:,:,0]উত্পাদন array([[1, 2],[1, 2]]), যা আসল a, যেমনটি হয় (b*a)[:,:,1]ইত্যাদি etc.

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.