In Numpy kann ich zwei Arrays Ende-zu-Ende mit np.append
oder verketten np.concatenate
:
>>> X = np.array([[1,2,3]])
>>> Y = np.array([[-1,-2,-3],[4,5,6]])
>>> Z = np.append(X, Y, axis=0)
>>> Z
array([[ 1, 2, 3],
[-1, -2, -3],
[ 4, 5, 6]])
Aber diese machen Kopien ihrer Eingabearrays:
>>> Z[0,:] = 0
>>> Z
array([[ 0, 0, 0],
[-1, -2, -3],
[ 4, 5, 6]])
>>> X
array([[1, 2, 3]])
Gibt es eine Möglichkeit, zwei Arrays zu einer Ansicht zu verketten , dh ohne zu kopieren? Würde das eine np.ndarray
Unterklasse erfordern ?
python
multidimensional-array
numpy
Fred Foo
quelle
quelle
concatenate
sie und die ursprünglichen Arrays durch Ansichten in die Verkettung ersetzen. Sieht so aus, als müsste ich das tun.Antworten:
Der zu einem Numpy-Array gehörende Speicher muss zusammenhängend sein. Wenn Sie die Arrays separat zugewiesen haben, werden sie zufällig im Speicher verteilt, und es gibt keine Möglichkeit, sie als Ansichts-Numpy-Array darzustellen.
Wenn Sie vorher wissen, wie viele Arrays Sie benötigen, können Sie stattdessen mit einem großen Array beginnen, das Sie zuvor zugewiesen haben, und jedes der kleinen Arrays eine Ansicht des großen Arrays sein lassen (z. B. durch Schneiden erhalten).
quelle
ndarray
Unterklassen verwenden, um mitmmap
'd Arrays zu arbeiten, aber ich denke, Speicherzuordnungen sind auch zusammenhängend ...numpy.empty
?Initialisieren Sie einfach das Array, bevor Sie es mit Daten füllen. Wenn Sie möchten, können Sie mehr Speicherplatz als erforderlich zuweisen, und es wird aufgrund der Funktionsweise von numpy nicht mehr RAM belegt.
Der Speicher wird nur verwendet, wenn Daten in das Array eingegeben wurden. Das Erstellen eines neuen Arrays aus der Verkettung von zwei Arrays wird für ein Dataset beliebiger Größe, dh ein Dataset> 1 GB oder so, niemals abgeschlossen.
quelle
Überhaupt nicht wirklich elegant, aber Sie können mit einem Tupel zum Speichern von Zeigern auf die Arrays an das herangehen, was Sie möchten. Jetzt habe ich keine Ahnung, wie ich es in dem Fall verwenden würde, aber ich habe solche Dinge schon einmal gemacht.
>>> X = np.array([[1,2,3]]) >>> Y = np.array([[-1,-2,-3],[4,5,6]]) >>> z = (X, Y) >>> z[0][:] = 0 >>> z (array([[0, 0, 0]]), array([[-1, -2, -3], [ 4, 5, 6]])) >>> X array([[0, 0, 0]])
quelle
Ich hatte das gleiche Problem und machte es umgekehrt. Nachdem ich normal (mit Kopie) verkettet hatte, ordnete ich die ursprünglichen Arrays neu zu, um Ansichten über das verkettete zu erhalten:
import numpy as np def concat_no_copy(arrays): """ Concats the arrays and returns the concatenated array in addition to the original arrays as views of the concatenated one. Parameters: ----------- arrays: list the list of arrays to concatenate """ con = np.concatenate(arrays) viewarrays = [] for i, arr in enumerate(arrays): arrnew = con[sum(len(a) for a in arrays[:i]): sum(len(a) for a in arrays[:i + 1])] viewarrays.append(arrnew) assert all(arr == arrnew) # return the view arrays, replace the old ones with these return con, viewarrays
Sie können es wie folgt testen:
def test_concat_no_copy(): arr1 = np.array([0, 1, 2, 3, 4]) arr2 = np.array([5, 6, 7, 8, 9]) arr3 = np.array([10, 11, 12, 13, 14]) arraylist = [arr1, arr2, arr3] con, newarraylist = concat_no_copy(arraylist) assert all(con == np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])) for old, new in zip(arraylist, newarraylist): assert all(old == new)
quelle
Sie können ein Array von Arrays erstellen, z.
>>> from numpy import * >>> a = array([1.0, 2.0, 3.0]) >>> b = array([4.0, 5.0]) >>> c = array([a, b]) >>> c array([[ 1. 2. 3.], [ 4. 5.]], dtype=object) >>> a[0] = 100.0 >>> a array([ 100., 2., 3.]) >>> c array([[ 100. 2. 3.], [ 4. 5.]], dtype=object) >>> c[0][1] = 200.0 >>> a array([ 100., 200., 3.]) >>> c array([[ 100. 200. 3.], [ 4. 5.]], dtype=object) >>> c *= 1000 >>> c array([[ 100000. 200000. 3000.], [ 4000. 5000.]], dtype=object) >>> a array([ 100., 200., 3.]) >>> # Oops! Copies were made...
Das Problem ist, dass bei Broadcast-Vorgängen Kopien erstellt werden (klingt wie ein Fehler).
quelle
Die Antwort basiert auf meiner anderen Antwort in Bezug auf ndarray-Zeilen in ndarray
X = np.array([[1,2,3]]) Y = np.array([[-1,-2,-3],[4,5,6]]) Z = np.array([None, None, None]) Z[0] = X[0] Z[1] = Y[0] Z[2] = Y[1] Z[0][0] = 5 # X would be changed as well print(X) Output: array([[5, 2, 3]]) # Let's make it a function! def concat(X, Y, copy=True): """Return an array of references if copy=False""" if copy is True: # deep copy return np.append(X, Y, axis=0) len_x, len_y = len(X), len(Y) ret = np.array([None for _ in range(len_x + len_y)]) for i in range(len_x): ret[i] = X[i] for j in range(len_y): ret[len_x + j] = Y[j] return ret
quelle