2016-09-11 1 views
2

glaube, ich habe einen zwei Arrays mit Ausnahme:eine Zufallszahl aus der Serie von Zahlen Zeichnung diejenigen, die in bestimmten Mengen

import numpy as np 
a = np.random.randint(0,10,10) 
b = np.random.randint(0,10,10) 

I zu erzeugen, will eine andere Länge-10-Array, deren i-te Eintrag eine zufällige ganze Zahl gezeichnet aus dem Satz ({0...9}minus die Elemente a[i] und b[i]).

ein relativer Neuling, wenn es um NumPy kommt, dachte ich, der einfachste Weg, dies zu tun sein könnte:

  1. die eingestellte Differenz x = {0...9} - (a[i] union b[i]) für jeden i
  2. np.random.choice(x[i], 1)
für jede i tun bekommen

Aber ich finde das ein wenig schwierig, weil ich nicht herausfinden kann, wie man setdiff1d elementweise über 2 Arrays abbildet. Gibt es einen offensichtlichen Weg, dies in NumPy zu tun (d. H. Idealerweise ohne auf Python-Sets usw. zurückgreifen zu müssen)?

+0

'Import Zufall random.sample (set (Bereich (0, 10)) Differenz ([a [i] , b [i]]), 1) [0] ' –

Antwort

2

Hier ist eine Möglichkeit:

In [87]: col = np.array((a, b)).T # Or as a better way np.column_stack((a,b)); suggested by @Divakar 

In [88]: r = np.arange(10) 

In [89]: np.ravel([np.random.choice(np.setdiff1d(r, i), 1) for i in col]) 
Out[89]: array([7, 8, 8, 6, 6, 8, 6, 5, 5, 6]) 

Oder als numpytonic Ansatz:

In [101]: def func(x):       
      return np.random.choice(np.setdiff1d(r, x), 1) 
    .....: 

In [102]: np.apply_along_axis(func, 1, col).ravel() 
Out[102]: array([6, 7, 9, 6, 4, 6, 7, 4, 0, 7]) 
+1

+1 Laden der Vektoren in eine Matrix und Transponieren, um die richtige Form zu erhalten. sehr NumPy-thonic, könnte man sagen! – gogurt

+1

Vielleicht verwenden Sie 'np.column_stack ((a, b))'? Außerdem würde ich "np.apply_along_axis" nicht für die Leistung vorschlagen, wofür ich NumPy normalerweise gedacht bin. – Divakar

+0

@Divakar In der Tat wäre das ein besserer Weg. Bezüglich der "apply_along_axis" hatte ich nie einen Benchmark, aber ich denke, dass das Listenverständnis schneller ist. – Kasramvd

0

Die np.random.choice Funktion scheint nicht sofort auf mehreren Sätzen arbeiten zu ermöglichen. Daher benötigen Sie eine Art von Schleife, um die separaten Aufrufe an np.random.choice für jedes Element der Ausgabe zu machen. Angesichts der Tatsache, dass eine Schleife benötigt wird, glaube ich nicht, dass man viel besser als Ihr Vorschlag in der Frage tun kann. Der folgende Code implementiert Ihre Idee und versteckt die erforderliche Schleife ein wenig durch eine Liste Verständnis mit.

import numpy as np 
a = np.random.randint(0,10,10) 
b = np.random.randint(0,10,10) 
domain = set(range(10)) 
res = [ np.random.choice(list(domain - set(avoid))) for avoid in zip(a, b) ] 
res = np.array(res) 
Verwandte Themen