অজগর কীভাবে জিরোসের সাথে আঙ্কুল অ্যারে প্যাড করবে


96

আমি জানতে চাই যে কীভাবে আমি ন্যালি সংস্করণ 1.5.0 এর সাথে পাইথন ২.6. using ব্যবহার করে জিরোসের সাহায্যে একটি 2 ডি নম্পি অ্যারে প্যাড করতে পারি। দুঃখিত! তবে এগুলি আমার সীমাবদ্ধতা। অতএব আমি ব্যবহার করতে পারি না np.pad। উদাহরণস্বরূপ, আমি জিরোসের aসাথে প্যাড করতে চাই যা এর আকার মেলে b। আমি এটি করতে চাইার কারণটি তাই আমি করতে পারি:

b-a

যেমন যে

>>> a
array([[ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.]])
>>> b
array([[ 3.,  3.,  3.,  3.,  3.,  3.],
       [ 3.,  3.,  3.,  3.,  3.,  3.],
       [ 3.,  3.,  3.,  3.,  3.,  3.],
       [ 3.,  3.,  3.,  3.,  3.,  3.]])
>>> c
array([[1, 1, 1, 1, 1, 0],
       [1, 1, 1, 1, 1, 0],
       [1, 1, 1, 1, 1, 0],
       [0, 0, 0, 0, 0, 0]])

আমি এটি করার একমাত্র উপায়টি সংযোজন, তবে এটি বেশ কুৎসিত বলে মনে হচ্ছে। সম্ভবত কোন ক্লিনার সমাধান ব্যবহার করছে b.shape?

সম্পাদনা করুন, MSeferts উত্তরের জন্য আপনাকে ধন্যবাদ। আমাকে এটি কিছুটা পরিষ্কার করতে হয়েছিল এবং আমি এটি পেয়েছি:

def pad(array, reference_shape, offsets):
    """
    array: Array to be padded
    reference_shape: tuple of size of ndarray to create
    offsets: list of offsets (number of elements must be equal to the dimension of the array)
    will throw a ValueError if offsets is too big and the reference_shape cannot handle the offsets
    """

    # Create an array of zeros with the reference shape
    result = np.zeros(reference_shape)
    # Create a list of slices from offset to offset + shape in each dimension
    insertHere = [slice(offsets[dim], offsets[dim] + array.shape[dim]) for dim in range(array.ndim)]
    # Insert the array in the result at the specified offsets
    result[insertHere] = array
    return result

উত্তর:


155

খুব সহজ, আপনি রেফারেন্স আকারটি ব্যবহার করে শূন্যযুক্ত একটি অ্যারে তৈরি করুন:

result = np.zeros(b.shape)
# actually you can also use result = np.zeros_like(b) 
# but that also copies the dtype not only the shape

এবং তারপরে আপনার প্রয়োজনীয় যেখানে অ্যারেটি প্রবেশ করুন:

result[:a.shape[0],:a.shape[1]] = a

এবং ভয়েলা আপনি এটি প্যাড করেছেন:

print(result)
array([[ 1.,  1.,  1.,  1.,  1.,  0.],
       [ 1.,  1.,  1.,  1.,  1.,  0.],
       [ 1.,  1.,  1.,  1.,  1.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.]])

আপনার উপরের বাম উপাদানটি কোথায় সন্নিবেশ করা উচিত তা আপনি যদি সংজ্ঞায়িত করেন তবে আপনি এটি আরও কিছুটা সাধারণ করে তুলতে পারেন

result = np.zeros_like(b)
x_offset = 1  # 0 would be what you wanted
y_offset = 1  # 0 in your case
result[x_offset:a.shape[0]+x_offset,y_offset:a.shape[1]+y_offset] = a
result

array([[ 0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  1.,  1.,  1.,  1.,  1.],
       [ 0.,  1.,  1.,  1.,  1.,  1.],
       [ 0.,  1.,  1.,  1.,  1.,  1.]])

তবে তারপরে সতর্কতা অবলম্বন করুন যে আপনার চেয়ে অনুমোদিত কোনও অফসেট না। জন্য x_offset = 2উদাহরণস্বরূপ এই ব্যর্থ হবে।


আপনার যদি একটি সালিশ সংখ্যার মাত্রা থাকে তবে আপনি মূল অ্যারেটি সন্নিবেশ করতে স্লাইসের একটি তালিকা সংজ্ঞায়িত করতে পারেন। আমি কিছুটা খেলার জন্য আকর্ষণীয় বলে মনে করেছি এবং এমন একটি প্যাডিং ফাংশন তৈরি করেছি যা অ্যারি এবং রেফারেন্সের একই সংখ্যার মাত্রা এবং অফসেটগুলি খুব বড় না হওয়া পর্যন্ত একটি সালিসি আকৃতির অ্যারে প্যাড করতে পারে (অফসেট সহ) can

def pad(array, reference, offsets):
    """
    array: Array to be padded
    reference: Reference array with the desired shape
    offsets: list of offsets (number of elements must be equal to the dimension of the array)
    """
    # Create an array of zeros with the reference shape
    result = np.zeros(reference.shape)
    # Create a list of slices from offset to offset + shape in each dimension
    insertHere = [slice(offset[dim], offset[dim] + array.shape[dim]) for dim in range(a.ndim)]
    # Insert the array in the result at the specified offsets
    result[insertHere] = a
    return result

এবং কিছু পরীক্ষার কেস:

import numpy as np

# 1 Dimension
a = np.ones(2)
b = np.ones(5)
offset = [3]
pad(a, b, offset)

# 3 Dimensions

a = np.ones((3,3,3))
b = np.ones((5,4,3))
offset = [1,0,0]
pad(a, b, offset)

কেবলমাত্র আমার প্রয়োজনের সংক্ষিপ্ত বিবরণটি: যদি padded = np.zeros(b.shape) padded[tuple(slice(0,n) for n in a.shape)] = a
উত্সে

162

NumPy 1.7.0 (যখন যুক্ত numpy.padকরা হয়েছিল) এখন বেশ পুরানো (এটি ২০১৩ সালে প্রকাশিত হয়েছিল) সুতরাং প্রশ্নটি যদি সেই ফাংশনটি ব্যবহার না করেই উপায় চেয়েছিল তবে আমি ভেবেছিলাম কীভাবে এটি ব্যবহার করে কীভাবে অর্জন করা যায় তা জেনে রাখা কার্যকর হতে পারে numpy.pad

এটি আসলে বেশ সহজ:

>>> import numpy as np
>>> a = np.array([[ 1.,  1.,  1.,  1.,  1.],
...               [ 1.,  1.,  1.,  1.,  1.],
...               [ 1.,  1.,  1.,  1.,  1.]])
>>> np.pad(a, [(0, 1), (0, 1)], mode='constant')
array([[ 1.,  1.,  1.,  1.,  1.,  0.],
       [ 1.,  1.,  1.,  1.,  1.,  0.],
       [ 1.,  1.,  1.,  1.,  1.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.]])

এই ক্ষেত্রে আমি 0এটির জন্য ডিফল্ট মান mode='constant'। তবে এটি স্পষ্টভাবে পাস করে এটি নির্দিষ্ট করা যেতে পারে:

>>> np.pad(a, [(0, 1), (0, 1)], mode='constant', constant_values=0)
array([[ 1.,  1.,  1.,  1.,  1.,  0.],
       [ 1.,  1.,  1.,  1.,  1.,  0.],
       [ 1.,  1.,  1.,  1.,  1.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.]])

দ্বিতীয় ক্ষেত্রে ( [(0, 1), (0, 1)]) বিভ্রান্ত বলে মনে হচ্ছে: প্রতিটি তালিকার আইটেম (এই ক্ষেত্রে টিপল) একটি মাত্রার সাথে সামঞ্জস্য করে এবং এতে আইটেমটি প্যাডিংয়ের (প্রথম উপাদান) আগে এবং পরে (দ্বিতীয় উপাদান) প্রতিনিধিত্ব করে। সুতরাং:

[(0, 1), (0, 1)]
         ^^^^^^------ padding for second dimension
 ^^^^^^-------------- padding for first dimension

  ^------------------ no padding at the beginning of the first axis
     ^--------------- pad with one "value" at the end of the first axis.

এক্ষেত্রে প্রথম এবং দ্বিতীয় অক্ষের প্যাডিং অভিন্ন, সুতরাং কেউ কেবল 2-টিউপলটিতেও যেতে পারে:

>>> np.pad(a, (0, 1), mode='constant')
array([[ 1.,  1.,  1.,  1.,  1.,  0.],
       [ 1.,  1.,  1.,  1.,  1.,  0.],
       [ 1.,  1.,  1.,  1.,  1.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.]])

যদি প্যাডিংয়ের আগে এবং তার পরে একরকম থাকে তবে টিপলটি বাদ দিতে পারে (যদিও এই ক্ষেত্রে প্রযোজ্য নয়):

>>> np.pad(a, 1, mode='constant')
array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  1.,  1.,  1.,  1.,  1.,  0.],
       [ 0.,  1.,  1.,  1.,  1.,  1.,  0.],
       [ 0.,  1.,  1.,  1.,  1.,  1.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.]])

অথবা যদি আগে এবং পরে প্যাডিং অক্ষের জন্য অভিন্ন তবে ভিন্ন হয় তবে আপনি অভ্যন্তরের টিপলগুলিতে দ্বিতীয় যুক্তিটিও বাদ দিতে পারেন:

>>> np.pad(a, [(1, ), (2, )], mode='constant')
array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  1.,  1.,  1.,  1.,  1.,  0.,  0.],
       [ 0.,  0.,  1.,  1.,  1.,  1.,  1.,  0.,  0.],
       [ 0.,  0.,  1.,  1.,  1.,  1.,  1.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.]])

তবে আমি সর্বদা স্পষ্ট ব্যবহার করতে পছন্দ করি, কারণ ভুল করা সহজ it's (যখন নুমপিসের প্রত্যাশা আপনার উদ্দেশ্য থেকে পৃথক হয়):

>>> np.pad(a, [1, 2], mode='constant')
array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  1.,  1.,  1.,  1.,  1.,  0.,  0.],
       [ 0.,  1.,  1.,  1.,  1.,  1.,  0.,  0.],
       [ 0.,  1.,  1.,  1.,  1.,  1.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.]])

এখানে নম্পপি মনে করে আপনি প্রতিটি অক্ষের পরে 1 টি উপাদান এবং 2 টি উপাদান দিয়ে সমস্ত অক্ষকে প্যাড করতে চেয়েছিলেন! এমনকি আপনি যদি অক্ষের 1 এবং 2 টি অক্ষরের জন্য 2 টি উপাদান দিয়ে প্যাড করতে চান।

প্যাডিংয়ের জন্য আমি টিপলগুলির তালিকাগুলি ব্যবহার করেছি, দ্রষ্টব্য যে এটি কেবল "আমার কনভেনশন", আপনি তালিকার তালিকাগুলি বা টিপলসগুলির টিপলস, বা অ্যারে এমনকি টিপলসও ব্যবহার করতে পারেন। নুমপি কেবল আর্গুমেন্টের দৈর্ঘ্য (বা এর দৈর্ঘ্য না থাকলে) এবং প্রতিটি আইটেমের দৈর্ঘ্য (বা যদি এর দৈর্ঘ্য থাকে) পরীক্ষা করে!


4
এটি সত্যিই ভাল ব্যাখ্যা করা হয়েছে। মূল ডকুমেন্টেশনের চেয়ে অনেক ভাল। ধন্যবাদ
এমআইনাট

mode='constant'বোধগম্য ডিফল্ট, সুতরাং শূন্যের সাথে প্যাডিং কোনও alচ্ছিক কীওয়ার্ডের প্রয়োজন ছাড়াই অর্জন করা যায়, যার ফলে কিছুটা আরও পঠনযোগ্য কোড বাড়ে।
ডিভেনেক্স

আমি কীভাবে কেবলমাত্র 3 ডি নম্পি অ্যারের তৃতীয় মাত্রায় প্যাডিং যুক্ত করতে পারি?
রমশা সিদ্দিকী

@ রমশাসিদিকী আপনি প্যাড করা উচিত নয় যে মাত্রাগুলির জন্য 0 সে ব্যবহার করতে পারেন।
MSefert

9

আমি বুঝতে পারি যে আপনার মূল সমস্যাটি হ'ল আপনাকে গণনা করা দরকার d=b-aতবে আপনার অ্যারেগুলির বিভিন্ন আকার রয়েছে। অন্তর্বর্তী প্যাডের প্রয়োজন নেইc

প্যাডিং ছাড়াই আপনি এটি সমাধান করতে পারেন:

import numpy as np

a = np.array([[ 1.,  1.,  1.,  1.,  1.],
              [ 1.,  1.,  1.,  1.,  1.],
              [ 1.,  1.,  1.,  1.,  1.]])

b = np.array([[ 3.,  3.,  3.,  3.,  3.,  3.],
              [ 3.,  3.,  3.,  3.,  3.,  3.],
              [ 3.,  3.,  3.,  3.,  3.,  3.],
              [ 3.,  3.,  3.,  3.,  3.,  3.]])

d = b.copy()
d[:a.shape[0],:a.shape[1]] -=  a

print d

আউটপুট:

[[ 2.  2.  2.  2.  2.  3.]
 [ 2.  2.  2.  2.  2.  3.]
 [ 2.  2.  2.  2.  2.  3.]
 [ 3.  3.  3.  3.  3.  3.]]

সত্য, তাঁর নির্দিষ্ট ক্ষেত্রে, তাকে প্যাড করার প্রয়োজন হয় না তবে এটি এমন খুব কম গাণিতিক ক্রিয়াকলাপগুলির মধ্যে একটি যেখানে প্যাডিং এবং আপনার পদ্ধতির সমতুল্য। তবুও সুন্দর উত্তর!
এমসিফার্ট

4
শুধু তাই নয় এটি শূন্য-প্যাডিংয়ের চেয়ে আরও মেমরির দক্ষ হতে পারে।
norok2

0

আপনার যদি অ্যারেতে 1s বেড়া যুক্ত করতে হয়:

>>> mat = np.zeros((4,4), np.int32)
>>> mat
array([[0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0]])
>>> mat[0,:] = mat[:,0] = mat[:,-1] =  mat[-1,:] = 1
>>> mat
array([[1, 1, 1, 1],
       [1, 0, 0, 1],
       [1, 0, 0, 1],
       [1, 1, 1, 1]])

0

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

def replicate_padding(arr):
    """Perform replicate padding on a numpy array."""
    new_pad_shape = tuple(np.array(arr.shape) + 2) # 2 indicates the width + height to change, a (512, 512) image --> (514, 514) padded image.
    padded_array = np.zeros(new_pad_shape) #create an array of zeros with new dimensions
    
    # perform replication
    padded_array[1:-1,1:-1] = arr        # result will be zero-pad
    padded_array[0,1:-1] = arr[0]        # perform edge pad for top row
    padded_array[-1, 1:-1] = arr[-1]     # edge pad for bottom row
    padded_array.T[0, 1:-1] = arr.T[0]   # edge pad for first column
    padded_array.T[-1, 1:-1] = arr.T[-1] # edge pad for last column
    
    #at this point, all values except for the 4 corners should have been replicated
    padded_array[0][0] = arr[0][0]     # top left corner
    padded_array[-1][0] = arr[-1][0]   # bottom left corner
    padded_array[0][-1] = arr[0][-1]   # top right corner 
    padded_array[-1][-1] = arr[-1][-1] # bottom right corner

    return padded_array

জটিলতা বিশ্লেষণ:

এর জন্য সর্বোত্তম সমাধান হ'ল নম্পির প্যাড পদ্ধতি। 5 রান গড়ে গড়ে তোলার পরে, আপেক্ষিক প্যাডিং সহ এনপি.প্যাড 8%উপরের সংজ্ঞায়িত ফাংশনটির চেয়ে ভাল। এটি দেখায় যে এটি আপেক্ষিক এবং শূন্য-প্যাডিং প্যাডিংয়ের জন্য মোটামুটি একটি সর্বোত্তম পদ্ধতি।


#My method, replicate_padding
start = time.time()
padded = replicate_padding(input_image)
end = time.time()
delta0 = end - start

#np.pad with edge padding
start = time.time()
padded = np.pad(input_image, 1, mode='edge')
end = time.time()
delta = end - start


print(delta0) # np Output: 0.0008790493011474609 
print(delta)  # My Output: 0.0008130073547363281
print(100*((delta0-delta)/delta)) # Percent difference: 8.12316715542522%
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.