webentwicklung-frage-antwort-db.com.de

"Klonen" von Zeilen- oder Spaltenvektoren

Manchmal ist es nützlich, einen Zeilen- oder Spaltenvektor in eine Matrix zu "klonen". Mit Klonen meine ich das Konvertieren eines Zeilenvektors wie z

[1,2,3]

In eine Matrix

[[1,2,3]
 [1,2,3]
 [1,2,3]
]

oder ein Spaltenvektor wie z

[1
 2
 3
]

in

[[1,1,1]
 [2,2,2]
 [3,3,3]
]

In Matlab oder Octave geht das ganz einfach:

 x = [1,2,3]
 a = ones(3,1) * x
 a =

    1   2   3
    1   2   3
    1   2   3

 b = (x') * ones(1,3)
 b =

    1   1   1
    2   2   2
    3   3   3

Ich möchte dies in numpy wiederholen, aber erfolglos

In [14]: x = array([1,2,3])
In [14]: ones((3,1)) * x
Out[14]:
array([[ 1.,  2.,  3.],
       [ 1.,  2.,  3.],
       [ 1.,  2.,  3.]])
# so far so good
In [16]: x.transpose() * ones((1,3))
Out[16]: array([[ 1.,  2.,  3.]])
# DAMN
# I end up with 
In [17]: (ones((3,1)) * x).transpose()
Out[17]:
array([[ 1.,  1.,  1.],
       [ 2.,  2.,  2.],
       [ 3.,  3.,  3.]])

Warum funktionierte die erste Methode (In [16]) nicht? Gibt es eine Möglichkeit, diese Aufgabe in python auf elegantere Weise zu lösen?

127
Boris Gorelik

Hier ist eine elegante, pythonische Methode:

>>> array([[1,2,3],]*3)
array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3]])

>>> array([[1,2,3],]*3).transpose()
array([[1, 1, 1],
       [2, 2, 2],
       [3, 3, 3]])

das Problem mit [16] scheint zu sein, dass die Transponierung für ein Array keine Auswirkung hat. Sie möchten wahrscheinlich stattdessen eine Matrix:

>>> x = array([1,2,3])
>>> x
array([1, 2, 3])
>>> x.transpose()
array([1, 2, 3])
>>> matrix([1,2,3])
matrix([[1, 2, 3]])
>>> matrix([1,2,3]).transpose()
matrix([[1],
        [2],
        [3]])
64
Peter

Verwenden numpy.tile :

>>> tile(array([1,2,3]), (3, 1))
array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3]])

oder zum Wiederholen von Spalten:

>>> tile(array([[1,2,3]]).transpose(), (1, 3))
array([[1, 1, 1],
       [2, 2, 2],
       [3, 3, 3]])
249
pv.

Beachten Sie zunächst, dass es bei numpys broadcasting -Operationen normalerweise nicht erforderlich ist, Zeilen und Spalten zu duplizieren. Beschreibungen finden Sie unter this und this .

Aber um dies zu tun, sind repeat ​​ und newaxis wahrscheinlich die besten Weg

In [12]: x = array([1,2,3])

In [13]: repeat(x[:,newaxis], 3, 1)
Out[13]: 
array([[1, 1, 1],
       [2, 2, 2],
       [3, 3, 3]])

In [14]: repeat(x[newaxis,:], 3, 0)
Out[14]: 
array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3]])

Dieses Beispiel gilt für einen Zeilenvektor, aber die Anwendung auf einen Spaltenvektor ist hoffentlich offensichtlich. repeat scheint dies gut zu buchstabieren, aber Sie können es auch wie in Ihrem Beispiel durch Multiplikation tun

In [15]: x = array([[1, 2, 3]])  # note the double brackets

In [16]: (ones((3,1))*x).transpose()
Out[16]: 
array([[ 1.,  1.,  1.],
       [ 2.,  2.,  2.],
       [ 3.,  3.,  3.]])
33
tom10

Ich denke, dass es das Beste ist, die Sendung in Numpy und schneller zu nutzen

Ich habe einen Vergleich wie folgt gemacht

import numpy as np
b = np.random.randn(1000)
In [105]: %timeit c = np.tile(b[:, newaxis], (1,100))
1000 loops, best of 3: 354 µs per loop

In [106]: %timeit c = np.repeat(b[:, newaxis], 100, axis=1)
1000 loops, best of 3: 347 µs per loop

In [107]: %timeit c = np.array([b,]*100).transpose()
100 loops, best of 3: 5.56 ms per loop

mit Broadcast etwa 15-mal schneller

8
smartkevin

np.broadcast_to ist noch schneller als np.tile:

x = np.arange(9)

%timeit np.broadcast_to(x, (6,9))
100000 loops, best of 3: 3.6 µs per loop

%timeit np.tile(x, (6,1))
100000 loops, best of 3: 8.4 µs per loop

Aber am schnellsten geht es bei @ tom10:

%timeit np.repeat(x[np.newaxis, :], 6, axis=0) 
100000 loops, best of 3: 3.15 µs per loop
6
Mateen Ulhaq

Sie können verwenden

np.tile(x,3).reshape((4,3))

kachel erzeugt die Wiederholungen des Vektors

und die Umformung verleiht ihm die gewünschte Form

2
thebeancounter

Eine saubere Lösung besteht darin, die äußere Produktfunktion von NumPy mit einem Vektor von Einsen zu verwenden:

np.outer(np.ones(n), x)

gibt n sich wiederholende Zeilen. Ändern Sie die Argumentreihenfolge, um sich wiederholende Spalten zu erhalten. So erhalten Sie die gleiche Anzahl von Zeilen und Spalten

np.outer(np.ones_like(x), x)
2
Jon Deaton
import numpy as np
x=np.array([1,2,3])
y=np.multiply(np.ones((len(x),len(x))),x).T
print(y)

ergibt:

[[ 1.  1.  1.]
 [ 2.  2.  2.]
 [ 3.  3.  3.]]
0
kibitzforu