2017-06-14 7 views
5

मैं एक सरणी के लिए सरणी a = [1, 2, 3, 4, 5, 6] और b = [1, 3, 5] और मैं a ऐसे मैप करने के लिए कि b में एक तत्व के बीच है कि a में प्रत्येक तत्व के लिए यह करने के लिए मैप किया जाएगा चाहते हैं b के सूचकांक कि ऊपरी सीमा है कि a शब्दों में। नहीं सबसे अच्छा विवरण में निहित है है, लेकिन यहाँ एक उदाहरणअजगर - आसान तरीका करने के लिए "तुलना" नक्शा एक-दूसरे

a = 1 -> 0 because a <= first element of b 
a = 2 -> 1 because b[0] < 2 <= b[1] and b[1] = 3 
a = 3 -> 1 
a = 4 -> 2 because b[1] < 4 <= b[2] 

तो अंतिम उत्पाद मैं चाहता हूँ f(a, b) = [0, 1, 1, 2, 2, 2]

है मैं मुझे पता है बस पाश और इसके लिए हल कर सकते हैं, लेकिन मैं सोच रहा था वहाँ है अगर एक चतुर, तेजी से (vectorized) रास्ता/numpy

+0

हल कर रहे हैं उन सरणियों हमेशा आदेश दिया रहे हैं? – taras

+0

हाँ आप मान सकते हैं कि उन्हें आदेश दिया गया है।यह भी मान सकते हैं कि बी के प्रत्येक तत्व में निहित है (इस बाधा के बिना एक अधिक सामान्य समाधान शानदार होगा, लेकिन मुझे लगता है कि यह आसान बनाता है) – Michael

उत्तर

7

उपयोग अजगर के bisect मॉड्यूल पांडा में यह करने के लिए:

from bisect import bisect_left 

a = [1, 2, 3, 4, 5, 6] 
b = [1, 3, 5] 

def f(_a, _b): 
    return [bisect_left(_b, i) for i in _a] 

print(f(a, b)) 

द्विविभाजित - ऐरे बिसेक्शन एल्गोरिदम

यह मॉड्यूल प्रत्येक सम्मिलन के बाद सूची को क्रमबद्ध किए बिना क्रमबद्ध क्रम में एक सूची बनाए रखने के लिए समर्थन प्रदान करता है। महंगा तुलना संचालन वाले सामानों की लंबी सूची के लिए, यह अधिक आम दृष्टिकोण पर सुधार हो सकता है। मॉड्यूल को बिसेक्ट कहा जाता है क्योंकि यह अपने काम को करने के लिए मूल बिसेक्शन एल्गोरिदम का उपयोग करता है। स्रोत कोड एल्गोरिदम के एक कामकाजी उदाहरण के रूप में सबसे उपयोगी हो सकता है (सीमा की स्थिति पहले से ही सही है!)।

निम्नलिखित कार्य प्रदान की जाती हैं:

bisect.bisect_left(a, x, lo=0, hi=len(a))

एक्स के लिए सम्मिलन बिंदु का पता लगाएँ एक में क्रमबद्ध व्यवस्था बनाए रखने के। पैरामीटर लो और हाय का उपयोग सूची के उप-समूह को निर्दिष्ट करने के लिए किया जा सकता है जिसे विचार किया जाना चाहिए; डिफ़ॉल्ट रूप से पूरी सूची का उपयोग किया जाता है। यदि x में पहले से मौजूद है, तो सम्मिलन बिंदु किसी भी मौजूदा प्रविष्टियों से पहले (बाईं ओर) होगा। वापसी मूल्य list.insert() पर पहले पैरामीटर के रूप में उपयोग के लिए उपयुक्त है मानते हैं कि पहले ही सॉर्ट किया गया है।

लौटे सम्मिलन बिंदु मैं विभाजन सरणी एक दो हिस्सों में तो यह है कि बाईं ओर के लिए all(val < x for val in a[lo:i]) और दाईं ओर के लिए all(val >= x for val in a[i:hi])

संदर्भ: https://docs.python.org/3/library/bisect.html

2

द्विविभाजित तेजी से होता है: समाधान ग्रहण सूचियों

a = [1, 2, 3, 4, 5, 6] 
b = [1, 3, 5] 

inds=[min(bisect_left(b,x),len(b)-1) for x in a] 

रिटर्न

[0, 1, 1, 2, 2, 2] 
संबंधित मुद्दे