পাইথন নম্পপি অ্যারের সমস্ত উপাদান প্রতিস্থাপন করুন যা কিছু মানের চেয়ে বড়


187

আমার কাছে একটি 2 ডি নম্পপি অ্যারে রয়েছে এবং এর মধ্যে সমস্ত মান 255.0 এর সাথে একটি থ্রেশহোল্ড টি এর চেয়ে বড় বা সমান প্রতিস্থাপন করতে চাই। আমার জ্ঞানের মতে, সর্বাধিক মৌলিক উপায় হ'ল:

shape = arr.shape
result = np.zeros(shape)
for x in range(0, shape[0]):
    for y in range(0, shape[1]):
        if arr[x, y] >= T:
            result[x, y] = 255
  1. এটি করার সর্বাধিক সংক্ষিপ্ত এবং অজগর উপায় কী?

  2. এটি করার জন্য কি কোনও দ্রুত (সম্ভবত কম সংক্ষিপ্ত এবং / বা কম পাইথোনিক) উপায় আছে?

এটি মানুষের মাথার এমআরআই স্ক্যানগুলির জন্য উইন্ডো / স্তরের সামঞ্জস্য সাব্রোটিনের অংশ হবে। 2D নিমপি অ্যারে হ'ল ইমেজ পিক্সেল ডেটা।


আরও তথ্যের জন্য, সূচকে এই পরিচয়টি একবার দেখুন ।
জিজ্ঞাসা

উত্তর:


329

আমি মনে করি এটি করার দ্রুত এবং সবচেয়ে সংক্ষিপ্ত উভয় উপায় হ'ল নুমপির অন্তর্নির্মিত ফ্যান্সি ইনডেক্সিং ব্যবহার করা। আপনার যদি ndarrayনামকরণ করা থাকে arr, আপনি নীচের মত সমস্ত উপাদানকে >255একটি মান দিয়ে প্রতিস্থাপন করতে পারেন x:

arr[arr > 255] = x

আমি এটি আমার মেশিনে 500 x 500 র্যান্ডম ম্যাট্রিক্স দিয়ে দৌড়েছি, সমস্ত মান> 0.5 এর পরিবর্তে 5 দিয়ে, এবং এটি গড়ে 7.59 মিমি নিয়েছে।

In [1]: import numpy as np
In [2]: A = np.random.rand(500, 500)
In [3]: timeit A[A > 0.5] = 5
100 loops, best of 3: 7.59 ms per loop

3
নোট করুন যে এটি ওপির মতো অ্যারে arrতৈরির পরিবর্তে বিদ্যমান অ্যারেটিকে পরিবর্তিত resultকরে if
জিজ্ঞাসা

1
পরিবর্তন না করে Aএকটি নতুন অ্যারে তৈরি করে এটি করার কোনও উপায় আছে কি ?
সোডিয়ামনেট্রেট

আমরা কি করব, যদি আমরা সূচকগুলিতে মানগুলি পরিবর্তন করতে চাই যা প্রদত্ত n এর একাধিক, যেমন [2], a [4], a [6], a [8] ..... এন = 2 এর জন্য?
lavee_singh

100 লুপগুলি, প্রতি
লুপটিতে

5
উল্লেখ্য: যদি তথ্য একটি পাইথন তালিকায় রয়েছে এই কাজ করে না, এটি একটি numpy অ্যারের মধ্যে (হতে হয়েছে np.array([1,2,3])
mjp

46

যেহেতু আপনি প্রকৃতপক্ষে একটি আলাদা অ্যারে চান arrযেখানে এটি রয়েছে arr < 255এবং 255অন্যথায় এটি সহজভাবে করা যেতে পারে:

result = np.minimum(arr, 255)

আরও সাধারণভাবে, নিম্ন এবং / বা উপরের সীমানার জন্য:

result = np.clip(arr, 0, 255)

আপনি যদি কেবল 255 এর বেশি মানগুলি বা আরও জটিল কিছু অ্যাক্সেস করতে চান তবে @ এমটিটান 8 এর উত্তরটি আরও সাধারণ, তবে np.clipএবং np.minimum(বা np.maximum) আপনার ক্ষেত্রে আরও সুন্দর এবং আরও দ্রুত:

In [292]: timeit np.minimum(a, 255)
100000 loops, best of 3: 19.6 µs per loop

In [293]: %%timeit
   .....: c = np.copy(a)
   .....: c[a>255] = 255
   .....: 
10000 loops, best of 3: 86.6 µs per loop

আপনি যদি এটি স্থানে করতে চান (অর্থাত্ arrতৈরির পরিবর্তে সংশোধন করুন result) আপনি এর outপ্যারামিটারটি ব্যবহার করতে পারেন np.minimum:

np.minimum(arr, 255, out=arr)

অথবা

np.clip(arr, 0, 255, arr)

( out=ফাংশনটির সংজ্ঞা হিসাবে একই ক্রমে যুক্তি যুক্ত হওয়ার পরে নামটি alচ্ছিক)

ইন-প্লেস মডিফিকেশনের জন্য, বুলিয়ান ইনডেক্সিং প্রচুর গতি বাড়িয়েছে (অনুলিপিটি তৈরি করে আলাদাভাবে না করে আলাদাভাবে তৈরি করা), তবে এখনও তত দ্রুত নয় minimum:

In [328]: %%timeit
   .....: a = np.random.randint(0, 300, (100,100))
   .....: np.minimum(a, 255, a)
   .....: 
100000 loops, best of 3: 303 µs per loop

In [329]: %%timeit
   .....: a = np.random.randint(0, 300, (100,100))
   .....: a[a>255] = 255
   .....: 
100000 loops, best of 3: 356 µs per loop

তুলনা করার জন্য, আপনি যদি নিজের মানগুলিকে ন্যূনতম পাশাপাশি সর্বাধিক সীমাবদ্ধ করতে চান তবে আপনাকে clipএই জাতীয় কিছু দিয়ে দুবার এটি করতে হবে না

np.minimum(a, 255, a)
np.maximum(a, 0, a)

বা,

a[a>255] = 255
a[a<0] = 0

1
আপনার সম্পূর্ণ মন্তব্যের জন্য আপনাকে অনেক ধন্যবাদ, তবে এনপি.সি.লিপ এবং এনপি.মিনিমাম এই ক্ষেত্রে আমার যা প্রয়োজন তা মনে হচ্ছে না, ওপিতে আপনি দেখতে পাবেন যে প্রান্তিক টি এবং প্রতিস্থাপনের মান (255) অগত্যা এক নয় সংখ্যা। তবে আমি এখনও আপনাকে পুঙ্খানুপুঙ্খতার জন্য একটি ভোট দিয়েছি। আবার ধন্যবাদ.
NLi10

আমরা কি করব, যদি আমরা সূচকগুলিতে মানগুলি পরিবর্তন করতে চাই যা প্রদত্ত n এর একাধিক, যেমন [2], a [4], a [6], a [8] ..... এন = 2 এর জন্য?
lavee_singh

@lavee_singh, যে কাজ করতে, আপনি ফালি, যা সাধারণত অবহেলিত তৃতীয় অংশে ব্যবহার করতে পারেন: a[start:stop:step]আপনার কাছ থেকে অ্যারের উপাদানের দেয় startকরার stop, কিন্তু প্রতিটি উপাদান পরিবর্তে, এটি শুধুমাত্র যে লাগে step(যদি অবহেলিত, এটা 1ডিফল্ট ভাবে )। সুতরাং সমস্ত a[::2] = 0
সন্ধ্যা

ধন্যবাদ আমার এই জাতীয় কিছু দরকার ছিল, যদিও আমি এটি সাধারণ তালিকাগুলির জন্য জানতাম, তবে আমি জানি না যে এটি কীভাবে নাম্পিয়ারে কাজ করে বা কীভাবে কাজ করে।
lavee_singh

14

আমি মনে করি whereফাংশনটি ব্যবহার করে আপনি এটি দ্রুত অর্জন করতে পারেন :

উদাহরণস্বরূপ, একটি নমপি অ্যারে 0.2 এর চেয়ে বেশি আইটেমগুলি সন্ধান করা এবং 0 এর সাথে প্রতিস্থাপন করা:

import numpy as np

nums = np.random.rand(4,3)

print np.where(nums > 0.2, 0, nums)

10

আপনি numpy.putmask ব্যবহার বিবেচনা করতে পারেন :

np.putmask(arr, arr>=T, 255.0)

এখানে নম্পির বিল্টিন ইনডেক্সিংয়ের সাথে পারফরম্যান্সের তুলনা করা হল:

In [1]: import numpy as np
In [2]: A = np.random.rand(500, 500)

In [3]: timeit np.putmask(A, A>0.5, 5)
1000 loops, best of 3: 1.34 ms per loop

In [4]: timeit A[A > 0.5] = 5
1000 loops, best of 3: 1.82 ms per loop

8

অন্য উপায়টি হ'ল ব্যবহার করা np.placeযা স্থান-প্রতিস্থাপন করে এবং বহুমাত্রিক অ্যারেগুলির সাথে কাজ করে:

import numpy as np

# create 2x3 array with numbers 0..5
arr = np.arange(6).reshape(2, 3)

# replace 0 with -10
np.place(arr, arr == 0, -10)

এটি আমিই সমাধানটি ব্যবহার করেছি কারণ এটিই আমি প্রথম এসেছি। আমি এবং অবিরত নির্বাচিত উত্তরের মধ্যে বড় পার্থক্য আছে কিনা তা অবাক করি। আপনি কি মনে করেন?
18:44

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

আমার ক্ষেত্রে np.placeঅন্তর্নির্মিত পদ্ধতির তুলনায় ধীর ছিল, যদিও এই মন্তব্যে বিপরীত দাবি করা হয়েছে ।
riyansh.legnd

3

আপনি আরও নমনীয়তার জন্য &, |(এবং / অথবা) ব্যবহার করতে পারেন :

5 এবং 10 এর মধ্যে মানসমূহ: A[(A>5)&(A<10)]

10 এর চেয়ে বড় বা 5 এর চেয়ে কম মানের: A[(A<5)|(A>10)]

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