webentwicklung-frage-antwort-db.com.de

Spalten in einem numpy Array tauschen?

from numpy import *
def swap_columns(my_array, col1, col2):
    temp = my_array[:,col1]
    my_array[:,col1] = my_array[:,col2]
    my_array[:,col2] = temp

Dann

swap_columns(data, 0, 1)

Funktioniert nicht Rufen Sie den Code jedoch direkt auf

temp = my_array[:,0]
my_array[:,0] = my_array[:,1]
my_array[:,1] = temp

Tut. Warum passiert das und wie kann ich es beheben? Der Fehler besagt, dass "IndexError: 0-d-Arrays nur ein einzelnes () oder eine Liste von Newaxes (und ein einzelnes ...) als Index verwenden können", was impliziert, dass die Argumente keine Ints sind? Ich habe bereits versucht, die cols in int umzuwandeln, aber das hat es nicht gelöst.

47

Hier gibt es zwei Probleme. Das erste ist, dass das data, das Sie an Ihre Funktion übergeben, anscheinend kein zweidimensionales NumPy-Array ist - zumindest wird dies in der Fehlermeldung angegeben.

Das zweite Problem ist, dass der Code nicht das tut, was Sie erwarten:

my_array = numpy.arange(9).reshape(3, 3)
# array([[0, 1, 2],
#        [3, 4, 5],
#        [6, 7, 8]])
temp = my_array[:, 0]
my_array[:, 0] = my_array[:, 1]
my_array[:, 1] = temp
# array([[1, 1, 2],
#        [4, 4, 5],
#        [7, 7, 8]])

Das Problem ist, dass Numpy Basic Slicing keine Kopien der tatsächlichen Daten erstellt, sondern eine Sicht auf dieselben Daten. Damit dies funktioniert, müssen Sie entweder explizit kopieren

temp = numpy.copy(my_array[:, 0])
my_array[:, 0] = my_array[:, 1]
my_array[:, 1] = temp

oder verwenden Sie Advanced Slicing

my_array[:,[0, 1]] = my_array[:,[1, 0]]
94
Sven Marnach

Folgendes finde ich am schnellsten:

my_array[:, 0], my_array[:, 1] = my_array[:, 1], my_array[:, 0].copy()

Zeitanalyse von:

import numpy as np
my_array = np.arange(900).reshape(30, 30)

ist wie folgt:

%timeit my_array[:, 0], my_array[:, 1] = my_array[:, 1], my_array[:, 0].copy()
The slowest run took 15.05 times longer than the fastest. This could mean that an intermediate result is being cached 
1000000 loops, best of 3: 1.72 µs per loop

Die erweiterten Slicing-Zeiten sind:

%timeit my_array[:,[0, 1]] = my_array[:,[1, 0]]
The slowest run took 7.38 times longer than the fastest. This could mean that an intermediate result is being cached 
100000 loops, best of 3: 6.9 µs per loop
24
blaz

Aufbauend auf der Antwort von @ Sven:

import numpy as np
my_array = np.arange(9).reshape(3, 3)
print my_array

[[0 1 2]
 [3 4 5]
 [6 7 8]]

def swap_cols(arr, frm, to):
    arr[:,[frm, to]] = arr[:,[to, frm]]

swap_cols(my_array, 0, 1)
print my_array

[[1 0 2]
 [4 3 5]
 [7 6 8]]

def swap_rows(arr, frm, to):
    arr[[frm, to],:] = arr[[to, frm],:]

my_array = np.arange(9).reshape(3, 3)
swap_rows(my_array, 0, 2)
print my_array

[[6 7 8]
 [3 4 5]
 [0 1 2]]
13
Renaud

Angenommen, Sie haben ein numpy-Array wie das folgende:

array([[ 0., -1.,  0.,  0.],
       [ 0.,  1.,  1.,  1.],
       [ 0.,  0., -1.,  0.],
       [ 0.,  0.,  0., -1.]])

Dies ist eine sehr elegante Art, die Spalten zu tauschen:

col1 = 0
col2 = 1    
my_array.T[[col1, col2]] = my_array.T[[col2, col1]]

Ergebnis:

array([[-1.,  0.,  0.,  0.],
       [ 1.,  0.,  1.,  1.],
       [ 0.,  0., -1.,  0.],
       [ 0.,  0.,  0., -1.]])
9
Jensun