दो सुन्न सरणियों का इंटरव्यू


84

मान लें कि निम्न सरणियाँ दी गई हैं:

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

कोई उन्हें कुशलतापूर्वक कैसे इंटरव्यू देगा ताकि किसी को इस तरह से तीसरा एरे मिल जाए

c = array([1,2,3,4,5,6])

यह माना जा सकता है कि length(a)==length(b)


1
कैसे के बारे में, एक ही सवाल है, लेकिन आप matrices interleave करने की कोशिश कर रहे हैं। यह एक और बी 3 आयामी हैं, और जरूरी नहीं कि पहले आयाम में समान आकार हो। नोट: केवल पहला आयाम इंटरलेय्ड होना चाहिए।
गेरोनिमो

जवाबों:


144

मुझे जोश का जवाब पसंद है। मैं सिर्फ एक अधिक सांसारिक जोड़ना चाहता था, हमेशा की तरह, और थोड़ा अधिक क्रिया समाधान। मुझे नहीं पता कि कौन अधिक कुशल है। मुझे उम्मीद है कि उनका भी इसी तरह का प्रदर्शन होगा।

import numpy as np
a = np.array([1,3,5])
b = np.array([2,4,6])

c = np.empty((a.size + b.size,), dtype=a.dtype)
c[0::2] = a
c[1::2] = b

1
जब तक वास्तव में गति वास्तव में महत्वपूर्ण नहीं है, मैं इसके साथ जाऊंगा क्योंकि यह बहुत अधिक व्यापक है जो किसी को भी फिर से देखने के लिए महत्वपूर्ण है।
जॉन साल्वेटियर

6
+1 मैंने समय के साथ खेला और आपका कोड आश्चर्यजनक रूप से इनपुट के आधार पर 2-5x तेज हो गया। मुझे अब भी इस प्रकार के संचालन की दक्षता गैर-लाभकारी लगती है, इसलिए timeitयदि कोई विशेष ऑपरेशन आपके कोड में एक अड़चन है, तो चीजों को परखने के लिए इसका उपयोग करना हमेशा उचित होता है । आमतौर पर चीजों को सुन्न करने के लिए एक से अधिक तरीके होते हैं, इसलिए निश्चित रूप से प्रोफ़ाइल कोड स्निपेट्स हैं।
जोशेल

@JoshAdel: मुझे लगता है कि अगर .reshapeसरणी की एक अतिरिक्त प्रतिलिपि बनाता है, तो वह 2x प्रदर्शन हिट की व्याख्या करेगा। मुझे नहीं लगता कि यह हमेशा एक प्रति बनाता है, हालांकि। मैं अनुमान लगा रहा हूं कि 5x का अंतर केवल छोटे सरणियों के लिए है?
पॉल

मेरे समाधान के लिए देख रहा है .flagsऔर परीक्षण .baseकर रहा है, यह 'एफ' प्रारूप के आकार जैसा दिखता है, जो vstacked डेटा की एक छिपी प्रतिलिपि बनाता है, इसलिए यह एक सरल दृश्य नहीं है जैसा कि मैंने सोचा था कि यह होगा। और अजीब तरह से 5x केवल किसी कारण के लिए मध्यवर्ती आकार के सरणियों के लिए है।
जोशेल

इस उत्तर का एक और फायदा यह है कि यह समान लंबाई के सरणियों तक सीमित नहीं है। यह nआइटम के साथ n-1आइटम बुनाई कर सकता है ।
एलियाडल

62

मैंने सोचा कि प्रदर्शन के संदर्भ में समाधान कैसे किए गए हैं, इसकी जाँच करना सार्थक हो सकता है। और यह परिणाम है:

यहां छवि विवरण दर्ज करें

यह स्पष्ट रूप से दर्शाता है कि सबसे उत्कीर्ण और स्वीकृत उत्तर (पॉल्स उत्तर) भी सबसे तेज विकल्प है।

कोड अन्य उत्तरों से लिया गया था और दूसरे प्रश्नोत्तर से :

# Setup
import numpy as np

def Paul(a, b):
    c = np.empty((a.size + b.size,), dtype=a.dtype)
    c[0::2] = a
    c[1::2] = b
    return c

def JoshAdel(a, b):
    return np.vstack((a,b)).reshape((-1,),order='F')

def xioxox(a, b):
    return np.ravel(np.column_stack((a,b)))

def Benjamin(a, b):
    return np.vstack((a,b)).ravel([-1])

def andersonvom(a, b):
    return np.hstack( zip(a,b) )

def bhanukiran(a, b):
    return np.dstack((a,b)).flatten()

def Tai(a, b):
    return np.insert(b, obj=range(a.shape[0]), values=a)

def Will(a, b):
    return np.ravel((a,b), order='F')

# Timing setup
timings = {Paul: [], JoshAdel: [], xioxox: [], Benjamin: [], andersonvom: [], bhanukiran: [], Tai: [], Will: []}
sizes = [2**i for i in range(1, 20, 2)]

# Timing
for size in sizes:
    func_input1 = np.random.random(size=size)
    func_input2 = np.random.random(size=size)
    for func in timings:
        res = %timeit -o func(func_input1, func_input2)
        timings[func].append(res)

%matplotlib notebook

import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure(1)
ax = plt.subplot(111)

for func in timings:
    ax.plot(sizes, 
            [time.best for time in timings[func]], 
            label=func.__name__)  # you could also use "func.__name__" here instead
ax.set_xscale('log')
ax.set_yscale('log')
ax.set_xlabel('size')
ax.set_ylabel('time [seconds]')
ax.grid(which='both')
ax.legend()
plt.tight_layout()

यदि आपके पास सुंबा उपलब्ध है तो आप एक फ़ंक्शन बनाने के लिए भी इसका उपयोग कर सकते हैं:

import numba as nb

@nb.njit
def numba_interweave(arr1, arr2):
    res = np.empty(arr1.size + arr2.size, dtype=arr1.dtype)
    for idx, (item1, item2) in enumerate(zip(arr1, arr2)):
        res[idx*2] = item1
        res[idx*2+1] = item2
    return res

यह अन्य विकल्पों की तुलना में थोड़ा तेज़ हो सकता है:

यहां छवि विवरण दर्ज करें


2
नोट के अलावा, स्वीकार किए जाते हैं जवाब है जिस तरह से तेजी के साथ एक देशी पायथन समाधान की तुलना में roundrobin()itertools व्यंजनों से।
ब्रैड सोलोमन

41

यहाँ एक लाइनर है:

c = numpy.vstack((a,b)).reshape((-1,),order='F')

16
वाह, यह बहुत ही अपठनीय है :) यह उन मामलों में से एक है जहां अगर आप कोड में एक उचित टिप्पणी नहीं लिखते हैं, तो यह आपको पागल बना सकता है।
इल्या कोगन

9
यह सिर्फ दो आम सुन्न आज्ञाओं को एक साथ मिलाता है। मुझे नहीं लगता कि यह अपठनीय है, हालांकि एक टिप्पणी कभी नहीं होती है।
जोश एडेल

1
@ जॉन एडेल, यह नहीं है numpy.vstack((a,b)).interweave():)
इल्या कोगन

6
@ इलिया: मैंने समारोह को .interleave()व्यक्तिगत रूप से कहा होगा :)
जोशेल

क्या करता reshapeहै?
दानीजेल

23

यहाँ पिछले कुछ की तुलना में एक सरल जवाब है

import numpy as np
a = np.array([1,3,5])
b = np.array([2,4,6])
inter = np.ravel(np.column_stack((a,b)))

इसके बाद interइसमें शामिल हैं:

array([1, 2, 3, 4, 5, 6])

यह उत्तर भी मामूली रूप से तेज प्रतीत होता है:

In [4]: %timeit np.ravel(np.column_stack((a,b)))
100000 loops, best of 3: 6.31 µs per loop

In [8]: %timeit np.ravel(np.dstack((a,b)))
100000 loops, best of 3: 7.14 µs per loop

In [11]: %timeit np.vstack((a,b)).ravel([-1])
100000 loops, best of 3: 7.08 µs per loop

10

यह दो सरणियों को इंटरलेव / इंटरले करेगा और मेरा मानना ​​है कि यह काफी पठनीय है:

a = np.array([1,3,5])      #=> array([1, 3, 5])
b = np.array([2,4,6])      #=> array([2, 4, 6])
c = np.hstack( zip(a,b) )  #=> array([1, 2, 3, 4, 5, 6])

2
मुझे यह सबसे ज्यादा पसंद है। इस तथ्य के बावजूद कि यह सबसे धीमा समाधान है।
किमस्तिक

लपेटें zipएक में listमूल्यह्रास चेतावनी से बचने के लिए
मिलो Wielondek

6

शायद यह @ जोशेल के समाधान से अधिक पठनीय है:

c = numpy.vstack((a,b)).ravel([-1])

2
ravelके orderमें तर्क प्रलेखन में से एक है C, F, A, या K। मुझे लगता है कि आप वास्तव में चाहते हैं .ravel('F'), फॉरट्रान ऑर्डर (कॉलम पहले) के लिए
निक टी

5

@ Xioxox का उत्तर सुधारना:

import numpy as np
a = np.array([1,3,5])
b = np.array([2,4,6])
inter = np.ravel((a,b), order='F')

1

vstack यकीन है कि एक विकल्प है, लेकिन आपके मामले के लिए अधिक सीधा समाधान विकल्प हो सकता है hstack

>>> a = array([1,3,5])
>>> b = array([2,4,6])
>>> hstack((a,b)) #remember it is a tuple of arrays that this function swallows in.
>>> array([1, 3, 5, 2, 4, 6])
>>> sort(hstack((a,b)))
>>> array([1, 2, 3, 4, 5, 6])

और अधिक महत्वपूर्ण यह की मनमानी आकार के लिए काम करता है aऔरb

इसके अलावा, आप बाहर की कोशिश करना चाहते हो सकता है dstack

>>> a = array([1,3,5])
>>> b = array([2,4,6])
>>> dstack((a,b)).flatten()
>>> array([1, 2, 3, 4, 5, 6])

अब आपके पास विकल्प हैं!


7
-1 से पहला जवाब क्योंकि सवाल का छंटनी से कोई लेना-देना नहीं है। +1 से दूसरा उत्तर, जो मैंने अब तक देखा सबसे अच्छा है। यही कारण है कि कई समाधानों को कई उत्तरों के रूप में पोस्ट किया जाना चाहिए। कृपया इसे कई उत्तरों में विभाजित करें।



0

मुझे ऐसा करने की आवश्यकता थी लेकिन किसी भी धुरी पर बहुआयामी सरणियों के साथ। यहाँ उस प्रभाव के लिए एक त्वरित सामान्य उद्देश्य कार्य है। इसमें एक ही कॉल हस्ताक्षर है np.concatenate, सिवाय इसके कि सभी इनपुट सरणियों का आकार बिल्कुल एक जैसा होना चाहिए ।

import numpy as np

def interleave(arrays, axis=0, out=None):
    shape = list(np.asanyarray(arrays[0]).shape)
    if axis < 0:
        axis += len(shape)
    assert 0 <= axis < len(shape), "'axis' is out of bounds"
    if out is not None:
        out = out.reshape(shape[:axis+1] + [len(arrays)] + shape[axis+1:])
    shape[axis] = -1
    return np.stack(arrays, axis=axis+1, out=out).reshape(shape)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.