2017-01-04 2 views
2

Gibt es eine Möglichkeit zu tun, die folgendenNumpy Array und weisen Werte in einzelner Zeile

import numpy as np 
x = np.arange(10) 
x[2:7] = 1 

In einer einzigen Zeile? So etwas wie

x = np.arange(10)[2:7] = 1 
+0

@Minato Nein, das ist nur ein Beispiel, ich suche eine allgemeine Lösung –

Antwort

6

One-Liner mit masking mit np.in1d und np.where für die Zuordnung von Werten -

np.where(np.in1d(range(10),range(2,7)), 1, range(10)) 

Probelauf -

In [28]: np.where(np.in1d(range(10),range(2,7)), 1, range(10)) 
Out[28]: array([0, 1, 1, 1, 1, 1, 1, 7, 8, 9]) 

Schritt-für-Schritt-Lauf -

Holen Sie sich die Maske, in der neue Werte zugewiesen werden sollen:

In [44]: np.in1d(range(10),range(2,7)) 
Out[44]: array([False, False, True, True, True, True, \ 
       True, False, False, False], dtype=bool) 

die Maske Verwenden alongwith np.where zwischen neuen Wert (=1) und den ursprünglich definierten Werte wählen - range(10):

In [45]: np.where(np.in1d(range(10),range(2,7)), 1, range(10)) 
Out[45]: array([0, 1, 1, 1, 1, 1, 1, 7, 8, 9]) 

Somit ist die Syntax zusammenzufassen, im Grunde -

np.where(np.in1d(range(10),range(2,7)), 1, range(10)) 
         ^  ^ ^ ^
         (1)  (2) (3) <--(4)--> 

(1) Länge des zu definierenden Arrays.

(2) Schnittgrenzen.

(3) Neue Werte, die als zweiter Schritt zugewiesen werden sollen.

(4) Werte, die zum Zeitpunkt der Definition zum Array initialisiert wurden.

Hier ist eine weiteres Beispiel Nutzung -

In [41]: np.where(np.in1d(range(9),range(2,7)), 99, range(10,19)) 
Out[41]: array([10, 11, 99, 99, 99, 99, 99, 17, 18]) 

Der ursprüngliche gestylten Code es wäre, zu reproduzieren -

können
x = np.arange(10,19) 
x[2:7] = 99 
+3

Während dies funktional eine ausgezeichnete Antwort ist, denke ich, dass dieser eine Liner viel weniger lesbar ist als die ursprüngliche Zweizeilenversion. Also, es sei denn, dass dies die Performance (Speicher oder Geschwindigkeit) verbessert, denke ich, dass der Zwei-Linien-Ansatz bevorzugt wird. Oder stellen Sie zumindest sicher, dass Sie den einen Liner ausreichend kommentieren. –

+1

@ HannesOvren Entspricht dem Lesbarkeitsproblem. Selbst mit Leistung/Gedächtnis wäre der ursprüngliche Zweiliner besser. Einige Kommentare/Erklärungen hinzugefügt. – Divakar

0

Sie np.hstack verwenden:

np.hstack((np.arange(2), np.ones(7-2), np.arange(7,10))) 

und multiplizieren np.ones mit welcher auch immer Nummer, die du brauchst. Es sollte einfach sein, es auf beliebige Eingabezahlen zu erweitern.

enter image description here

1

Während Divakar Antwort die Arbeit erledigt, ist es nicht gut für die Lesbarkeit. Es gibt einen etwas närrischeren Weg, dies zu tun, indem man numpy.r_ verwendet, was im Wesentlichen eine Verkettung ausführt, aber Sie können Arrays mithilfe von Slices spezifizieren.

Aus den Beispielen in der Dokumentation (etwas von mir geändert):

>>> np.r_[1:4, 0, 0, 4:7] 
array([1, 2, 3, 0, 0, 4, 5, 6]) 
>>> np.r_[-1:1:6j, [0]*3, 5, 6] 
array([-1. , -0.6, -0.2, 0.2, 0.6, 1. , 0. , 0. , 0. , 5. , 6. ]) 

Für Ihr spezielles Beispiel

>>> np.r_[0:2, [1,]*5, 7:10] 
array([0, 1, 1, 1, 1, 1, 1, 7, 8, 9]) 
Verwandte Themen