2017-12-08 17 views
2

私はthisを見ましたが、私の質問にはあまり答えていません。配列を使ったナンディ配列の作成

私は配列を持っている:

x = np.array([0, 1, 2]) 

私はこれ欲しい:

y = np.array([[0,1], [0,2], [1,0], [1,2], [2,0], [2,1]]) 

私は配列xの(のはiそれを呼びましょう)それぞれの値を取り、作成したい、つまりx.shape[0]-1新を他のすべての値がxであり、iを除く配列

本質的にyには、対角要素のない3x3行列のインデックスが含まれています。

私は、私に来ていないだけの、これをやっている簡単な、pythonicの方法があると感じています。

答えて

1

アプローチ#1:一つのアプローチは次のようになります -

x[np.argwhere(~np.eye(len(x),dtype=bool))] 

アプローチ#2:2つの段階で -

r = np.arange(len(x)) 
out = x[np.argwhere(r[:,None]!=r)] 

アプローチ#3:パフォーマンスのために、それかもしれませんそれらの対の座標を作成してからマスクする方がよいでしょう。 paiwise座標を取得するには、のはそうのように、cartesian_product_transposeを使ってみましょう -

r = np.arange(len(x)) 
mask = r[:,None]!=r 
out = cartesian_product_transpose(x,x)[mask.ravel()] 

アプローチ#4:別を再び性能指標として意味、マスキングまでコピーを作成することを回避するnp.broadcast_toで -

n = len(x) 
r = np.arange(n) 
mask = r[:,None]!=r 
c0 = np.broadcast_to(x[:,None], (n, n))[mask] 
c1 = np.broadcast_to(x, (n,n))[mask] 
out = np.column_stack((c0,c1)) 

ランタイムテスト -

In [382]: x = np.random.randint(0,9,(1000)) 

# @tom10's soln 
In [392]: %timeit list(itertools.permutations(x, 2)) 
10 loops, best of 3: 62 ms per loop 

In [383]: %%timeit 
    ...: x[np.argwhere(~np.eye(len(x),dtype=bool))] 
100 loops, best of 3: 11.4 ms per loop 

In [384]: %%timeit 
    ...: r = np.arange(len(x)) 
    ...: out = x[np.argwhere(r[:,None]!=r)] 
100 loops, best of 3: 12.9 ms per loop 

In [388]: %%timeit 
    ...: r = np.arange(len(x)) 
    ...: mask = r[:,None]!=r 
    ...: out = cartesian_product_transpose(x,x)[mask.ravel()] 
100 loops, best of 3: 16.5 ms per loop 

In [389]: %%timeit 
    ...: n = len(x) 
    ...: r = np.arange(n) 
    ...: mask = r[:,None]!=r 
    ...: c0 = np.broadcast_to(x[:,None], (n, n))[mask] 
    ...: c1 = np.broadcast_to(x, (n,n))[mask] 
    ...: out = np.column_stack((c0,c1)) 
100 loops, best of 3: 6.72 ms per loop 
+0

ありがとう! tom10が示唆しているように、これはスケーラブルですか? – StatsSorceress

+0

@StatsSorceressする必要があります! – Divakar

+1

@StatsSorceress 1000 Elemsアレイ上のすべてのポストされたアプローチのタイミングを追加しました。 – Divakar

0

これは、本当にスピードなどを必要としない限り、numpy純粋なPythonはよりクリーンなソリューションを提供します:

import itertools 

y = itertools.permutations([0, 1, 2], 2) 

# [(0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1)] 
+0

ありがとう!これは単なるMWEだったので、スケーラブルなソリューションが好きです。 – StatsSorceress

関連する問題