Angenommen, die folgenden Arrays sind angegeben:
a = array([1,3,5])
b = array([2,4,6])
Wie würde man sie effizient verweben, so dass man ein drittes Array wie dieses erhält?
c = array([1,2,3,4,5,6])
Es ist davon auszugehen, dass length(a)==length(b)
.
Antworten:
Ich mag Joshs Antwort. Ich wollte nur eine profanere, üblichere und etwas ausführlichere Lösung hinzufügen. Ich weiß nicht, was effizienter ist. Ich gehe davon aus, dass sie eine ähnliche Leistung haben werden.
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
quelle
timeit
zu testen, wenn eine bestimmte Operation einen Engpass in Ihrem Code darstellt. Es gibt normalerweise mehr als eine Möglichkeit, Dinge in Numpy zu erledigen, also definitiv Profilcode-Schnipsel..reshape
eine zusätzliche Kopie des Arrays erstellt wird, würde dies einen 2x Performance-Hit erklären. Ich denke jedoch nicht, dass es immer eine Kopie macht. Ich vermute, der 5x Unterschied ist nur für kleine Arrays?.flags
und.base
sie teste, sieht es so aus, als würde durch die Umformung in das 'F'-Format eine versteckte Kopie der v-gestapelten Daten erstellt. Es ist also keine einfache Ansicht, wie ich es mir vorgestellt habe. Und seltsamerweise ist das 5x aus irgendeinem Grund nur für Arrays mittlerer Größe geeignet.n
Gegenstände mitn-1
Gegenständen weben .Ich dachte, es könnte sich lohnen, die Leistung der Lösungen zu überprüfen. Und das ist das Ergebnis:
Dies zeigt deutlich, dass die am besten bewertete und akzeptierte Antwort (Pauls Antwort) auch die schnellste Option ist.
Der Code wurde von den anderen Antworten und aus genommen einem anderen Q & A :
# 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()
Nur für den Fall, dass Sie numba zur Verfügung haben, können Sie damit auch eine Funktion erstellen:
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
Es könnte etwas schneller sein als die anderen Alternativen:
quelle
roundrobin()
den itertools-Rezepten.Hier ist ein Einzeiler:
c = numpy.vstack((a,b)).reshape((-1,),order='F')
quelle
numpy.vstack((a,b)).interweave()
:).interleave()
persönlichreshape
dasHier ist eine einfachere Antwort als einige der vorherigen
import numpy as np a = np.array([1,3,5]) b = np.array([2,4,6]) inter = np.ravel(np.column_stack((a,b)))
Danach
inter
enthält:array([1, 2, 3, 4, 5, 6])
Diese Antwort scheint auch etwas schneller zu sein:
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
quelle
Dies wird die beiden Arrays verschachteln / verschachteln und ich glaube, es ist gut lesbar:
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])
quelle
zip
in einerlist
Abschreibung Warnung zu vermeidenVielleicht ist dies besser lesbar als die Lösung von @ JoshAdel:
c = numpy.vstack((a,b)).ravel([-1])
quelle
ravel
‚sorder
Argument in der Dokumentation ist eine derC
,F
,A
, oderK
. Ich denke, Sie wollen wirklich.ravel('F')
, für FORTRAN-Bestellung (Spalte zuerst)Verbesserung der Antwort von @ xioxox:
import numpy as np a = np.array([1,3,5]) b = np.array([2,4,6]) inter = np.ravel((a,b), order='F')
quelle
vstack
Sicher ist eine Option, aber eine einfachere Lösung für Ihren Fall könnte die seinhstack
>>> 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])
und was noch wichtiger ist, dies funktioniert für beliebige Formen von
a
undb
Vielleicht möchten Sie es auch ausprobieren
dstack
>>> a = array([1,3,5]) >>> b = array([2,4,6]) >>> dstack((a,b)).flatten() >>> array([1, 2, 3, 4, 5, 6])
Du hast jetzt Optionen!
quelle
Noch ein Einzeiler:
np.vstack((a,b)).T.ravel()
Noch einer:
np.stack((a,b),1).ravel()
quelle
Man kann es auch versuchen
np.insert
. (Lösung von Interleave-Numpy-Arrays migriert )import numpy as np a = np.array([1,3,5]) b = np.array([2,4,6]) np.insert(b, obj=range(a.shape[0]), values=a)
Weitere Informationen finden Sie im
documentation
undtutorial
.quelle
Ich musste dies tun, aber mit mehrdimensionalen Arrays entlang einer beliebigen Achse. Hier ist eine schnelle Allzweckfunktion zu diesem Zweck. Es hat dieselbe Aufrufsignatur wie
np.concatenate
, außer dass alle Eingabearrays genau dieselbe Form haben müssen.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)
quelle