2014-01-22 9 views
9

In Python kann ich 2 Variablen durch mehrere Affektation austauschen; es funktioniert auch mit Listen:Zeilenwechsel in Numpy

l1,l2=[1,2,3],[4,5,6] 
l1,l2=l2,l1 
print(l1,l2) 
>>> [4, 5, 6] [1, 2, 3] 

Aber wenn ich 2 Zeilen eines numpy Array austauschen möchten (zum Beispiel in dem Gauß-Algorithmus), scheitert es:

import numpy as np 
a3=np.array([[1,2,3],[4,5,6]]) 
print(a3) 
a3[0,:],a3[1,:]=a3[1,:],a3[0,:] 
print(a3) 
>>> [[1 2 3] 
    [4 5 6]] 
    [[4 5 6] 
    [4 5 6]] 

Ich dachte, dass für eine seltsamer Grund, die beiden Spalten zeigten jetzt auf die gleichen Werte; aber das ist nicht der Fall, da nach den vorhergehenden Zeilen a3 [0,0] ändert, aber nicht a3 [1,0].

Ich habe herausgefunden, wie mit diesem Problem zu tun: zum Beispiel a3[0,:],a3[1,:]=a3[1,:].copy(),a3[0,:].copy() funktioniert. Aber kann jemand erklären, warum der Austausch mit mehreren Affekten mit numpigen Reihen scheitert? Meine Fragen betreffen die grundlegende Arbeit von Python und Numpy.

+2

Bitte finden Sie [die Antwort auf diese Frage] (http://stackoverflow.com/a/14933939/1600898) für die Erklärung. – user4815162342

+0

Okay, danke, diese Frage wurde nicht automatisch in der Liste der möglichen Duplikate vorgeschlagen. – JPG

+0

Kein Problem - der einzige Grund, warum ich davon weiß, ist, weil ich darauf geantwortet habe. – user4815162342

Antwort

14

Dies funktioniert so, wie Sie es wollen:

a3[[0,1]] = a3[[1,0]] 

Die beiden getrennten Zuordnungen in der Tupel Zuordnung nicht in Bezug auf einander gepuffert; ein passiert nach dem anderen, führt das Überschreiben Ihrer

+0

+1 Schön, dass das, was ein Ärgernis ist, wenn du versuchst, 'a [[0, 1, 1]] + = 1' zu tun und der Gegenstand an der Position' 1' nur einmal inkrementiert wird, kann zu deinem Vorteil verwendet werden, um Reihen zu tauschen . – Jaime

+0

Ja; Ich brauchte eine Weile, um die Logik dahinter zu verstehen. So glücklich mit dem neuen np.add.at; Tatsächlich schreibe ich jetzt gerade ein Stück Code, das war eine entsetzlich langsame Python-Schleife. –

+0

Für Summen ist 'np.bincount' typischerweise viel schneller als' np.add.at', 50x habe ich gerade versucht: 'a = np.zeros ((1000,), dtype = np.intp); b = np.random.randint (1000, Größe = 100000); c = np.random.randint (1000000, Größe = 100000); In [10]:% zeitraum np.add.at (a, b, c); 100 Schleifen, Best of 3: 19,3 ms pro Schleife; In [11]:% Zeit a + np.bincount (b, Gewichte = c, minlength = 1000); 1000 Loops, Best of 3: 451 μs pro Loop. – Jaime