নম্পি যেখানে একাধিক শর্ত কাজ করে


132

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

 dists[(np.where(dists >= r)) and (np.where(dists <= r + dr))]

তবে এটি কেবল শর্তের জন্য নির্বাচন করে

 (np.where(dists <= r + dr))

যদি আমি অস্থায়ী পরিবর্তনশীল ব্যবহার করে ক্রমানুসারে কমান্ডগুলি করি তবে এটি ঠিকঠাক কাজ করে। উপরের কোডটি কেন কাজ করে না এবং আমি কীভাবে এটি কাজ করব?

চিয়ার্স

উত্তর:


203

আপনার নির্দিষ্ট ক্ষেত্রে সবচেয়ে ভাল উপায় হ'ল আপনার দুটি মানদণ্ডকে একটি মানদণ্ডে পরিবর্তন করা:

dists[abs(dists - r - dr/2.) <= dr/2.]

এটি শুধুমাত্র এক বুলিয়ান অ্যারে তৈরি করে, এবং আমার মতে পড়তে কারণ এটা বলে সহজ, হয় distএকটি মধ্যে drবা r? (যদিও আমি rআপনার আগ্রহের কেন্দ্রটি শুরু করার পরিবর্তে পুনরায় সংজ্ঞায়িত করব , তাই r = r + dr/2.) তবে এটি আপনার প্রশ্নের উত্তর দেয় না।


আপনার প্রশ্নের উত্তর: আপনার যদি
প্রয়োজন হয় না whereতবে আপনি যদি কেবলমাত্র সেই উপাদানগুলির ফিল্টার করার চেষ্টা করছেন distsযা আপনার মানদণ্ডের সাথে খাপ খায় না:

dists[(dists >= r) & (dists <= r+dr)]

কারণ &আপনাকে একটি এলিমেন্টওয়াইজ দেবে and(প্রথম বন্ধনী প্রয়োজনীয়)।

বা, যদি আপনি whereকোনও কারণে ব্যবহার করতে চান তবে আপনি এটি করতে পারেন:

 dists[(np.where((dists >= r) & (dists <= r + dr)))]

কেন:
এটি কাজ না করার কারণ হ'ল np.whereবুলিয়ান অ্যারে নয়, সূচকগুলির তালিকা ফিরিয়ে দেয়। আপনি andদুটি সংখ্যার তালিকার মধ্যে যাওয়ার চেষ্টা করছেন , যার অবশ্যই আপনার True/ Falseআশা করা মানগুলি নেই। যদি aএবং bউভয় Trueমান হয়, তবে a and bফেরত দেয় b। তাই এরকম কিছু বলার সাথে সাথে [0,1,2] and [2,3,4]আপনাকে দেবে [2,3,4]। এখানে এটি কার্যকর হয়:

In [230]: dists = np.arange(0,10,.5)
In [231]: r = 5
In [232]: dr = 1

In [233]: np.where(dists >= r)
Out[233]: (array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),)

In [234]: np.where(dists <= r+dr)
Out[234]: (array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12]),)

In [235]: np.where(dists >= r) and np.where(dists <= r+dr)
Out[235]: (array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12]),)

আপনি যা তুলনা করার প্রত্যাশা করেছিলেন তা হ'ল উদাহরণস্বরূপ, বুলিয়ান অ্যারে

In [236]: dists >= r
Out[236]: 
array([False, False, False, False, False, False, False, False, False,
       False,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True], dtype=bool)

In [237]: dists <= r + dr
Out[237]: 
array([ True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True, False, False, False, False, False,
       False, False], dtype=bool)

In [238]: (dists >= r) & (dists <= r + dr)
Out[238]: 
array([False, False, False, False, False, False, False, False, False,
       False,  True,  True,  True, False, False, False, False, False,
       False, False], dtype=bool)

এখন আপনি np.whereসম্মিলিত বুলিয়ান অ্যারে কল করতে পারেন :

In [239]: np.where((dists >= r) & (dists <= r + dr))
Out[239]: (array([10, 11, 12]),)

In [240]: dists[np.where((dists >= r) & (dists <= r + dr))]
Out[240]: array([ 5. ,  5.5,  6. ])

অথবা সহজভাবে অভিনব সূচক ব্যবহার করে বুলিয়ান অ্যারের সাথে মূল অ্যারের সূচক করুন

In [241]: dists[(dists >= r) & (dists <= r + dr)]
Out[241]: array([ 5. ,  5.5,  6. ])

61

গৃহীত উত্তর সমস্যাটি যথেষ্ট ভালভাবে ব্যাখ্যা করেছিল। যাইহোক, একাধিক শর্ত প্রয়োগের জন্য যত বেশি নম্পাইথোনিক পদ্ধতি অবলম্বন করা হয় তা হ'ল ন্যূনীয় লজিক্যাল ফাংশন । এই এসিতে আপনি ব্যবহার করতে পারেন np.logical_and:

np.where(np.logical_and(np.greater_equal(dists,r),np.greater_equal(dists,r + dr)))

11

এখানে আকর্ষণীয় একটি বিষয়; সাধারণত ওআর এবং এ্যান্ড ব্যবহারের পদ্ধতিও এক্ষেত্রে কার্যকর হবে তবে একটি ছোট পরিবর্তন দিয়ে। "এবং" এর পরিবর্তে এবং "বা" পরিবর্তে অ্যাম্পারস্যান্ড (&) এবং পাইপ অপারেটর (|) ব্যবহার করুন এবং এটি কার্যকর হবে।

যখন আমরা 'এবং' ব্যবহার করি :

ar = np.array([3,4,5,14,2,4,3,7])
np.where((ar>3) and (ar<6), 'yo', ar)

Output:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

যখন আমরা অ্যাম্পারস্যান্ড (&) ব্যবহার করি :

ar = np.array([3,4,5,14,2,4,3,7])
np.where((ar>3) & (ar<6), 'yo', ar)

Output:
array(['3', 'yo', 'yo', '14', '2', 'yo', '3', '7'], dtype='<U11')

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

হালনাগাদ

একজন ব্যবহারকারী জিজ্ঞাসা করলেন, কেন প্রথম বন্ধনের অভ্যন্তরে (আর> 3) এবং (আর <6) দেওয়ার প্রয়োজন আছে? ভাল এখানে জিনিস। আমি এখানে কী ঘটছে সে সম্পর্কে কথা বলা শুরু করার আগে পাইথনের অপারেটর অগ্রাধিকার সম্পর্কে আপনার জানা দরকার।

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

মামলা 1:

np.where( ar>3 & ar<6, 'yo', ar)
np.where( np.array([3,4,5,14,2,4,3,7])>3 & np.array([3,4,5,14,2,4,3,7])<6, 'yo', ar)

যেহেতু এখানে কোনও বন্ধনী নেই, বিটওয়াইস অপারেটর ( &) এখানে বিভ্রান্ত হয়ে উঠছে যে আপনি এমনকি এটি যৌক্তিক ও এর জন্য জিজ্ঞাসা করছেন কেননা অপারেটর অগ্রাধিকার সারণীতে যদি আপনি দেখেন তবে &অগ্রাধিকার দেওয়া হয় <বা >অপারেটরগুলি। এখানে সর্বনিম্ন নজরে থেকে সর্বোচ্চ অগ্রাধিকার পর্যন্ত সারণীটি এখানে রয়েছে।

এখানে চিত্র বর্ণনা লিখুন

এটি এমনকি অপারেশনও সম্পাদন করে না <এবং >একটি যৌক্তিক এবং অপারেশন করতে বলা হচ্ছে। সুতরাং যে এটি ত্রুটি দেয়।

অপারেটর অগ্রাধিকার সম্পর্কে আরও জানতে নিম্নলিখিত লিঙ্কটি পরীক্ষা করে দেখতে পারেন

এখন কেস 2 তে:

আপনি যদি বন্ধনী ব্যবহার করেন তবে আপনি কী করবেন তা স্পষ্টভাবে দেখতে পাবেন।

np.where( (ar>3) & (ar<6), 'yo', ar)
np.where( (array([False,  True,  True,  True, False,  True, False,  True])) & (array([ True,  True,  True, False,  True,  True,  True, False])), 'yo', ar)

সত্য এবং মিথ্যা দুটি অ্যারে। এবং আপনি এগুলিতে সহজেই যৌক্তিক ও পরিচালনা করতে পারেন। যা আপনাকে দেয়:

np.where( array([False,  True,  True, False, False,  True, False, False]),  'yo', ar)

এবং আপনি অবশ্যই জানেন, এনপি.এই কোথাও, প্রদত্ত ক্ষেত্রে, যেখানেই সত্য, প্রথম মান নির্ধারিত করে (যেমন এখানে 'ইয়ো') এবং যদি মিথ্যা হয় তবে অন্যটি (যেমন এখানে আসল রাখা)।

এখানেই শেষ. আমি আশা করি আমি কোয়েরিটি ভালভাবে ব্যাখ্যা করেছি।


1
কেন আপনি ()চারপাশে রাখা আছে (ar>3)এবং (ar>6)?
RTrain3k

এটা সত্যিই একটি ভাল প্রশ্ন। এটি এমন একটি ভাল প্রশ্ন যা আমাকে নিজেরাই ভাবতে হয়েছিল যে পৃথিবীতে যা দরকার তা এটি। তাই আমি করেছি, একজন সহকর্মীকেও জিজ্ঞাসা করেছি এবং আমরা এখন আলোচনা করেছি আপনার কাছে আমার সমাধান আছে। একটি আপডেট হিসাবে উত্তরে এটি রাখা। এটি সত্যিই সহজ তবে সত্য বোঝা একটি কঠিন জিনিস।
অমিত আমোলা

আপডেটটি আর্ট্রিন 3 কে দেখুন, আমি আপনার প্রশ্নের উত্তর দিয়েছি query
অমিত আমোলা

5

আমি এই np.vectorizeধরনের কাজের জন্য ব্যবহার করতে চাই । নিম্নোক্ত বিবেচনা কর:

>>> # function which returns True when constraints are satisfied.
>>> func = lambda d: d >= r and d<= (r+dr) 
>>>
>>> # Apply constraints element-wise to the dists array.
>>> result = np.vectorize(func)(dists) 
>>>
>>> result = np.where(result) # Get output.

আপনি পরিষ্কার আউটপুট জন্য np.argwhereপরিবর্তে ব্যবহার করতে পারেন np.where। তবে এটি আপনার কল :)

আশা করি এটা সাহায্য করবে.



2

এই কাজ করা উচিত:

dists[((dists >= r) & (dists <= r+dr))]

সবচেয়ে মার্জিত উপায় ~~



0

আমি এই সহজ উদাহরণ কাজ করেছি

import numpy as np

ar = np.array([3,4,5,14,2,4,3,7])

print [X for X in list(ar) if (X >= 3 and X <= 6)]

>>> 
[3, 4, 5, 4, 3]

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