2012-09-20 9 views
12

A numpyのインデックスの単純例を返します:numpyのインデックス:残り

In: a = numpy.arange(10) 
In: sel_id = numpy.arange(5) 
In: a[sel_id] 
Out: array([0,1,2,3,4]) 

にはどうすればsel_idでインデックス化されていない配列の残りを返すのですか?私が考えることは:

In: numpy.array([x for x in a if x not in a[id]]) 
out: array([5,6,7,8,9]) 

もっと簡単な方法はありますか?

+0

これは1回限りの操作ですか?または、あなたは 'sel_id'を再利用します(それは否定です)。また、多次元の場合、または1Dの場合だけに興味がありますか? – mgilson

+0

私のアプリケーションでは、それは多次元の大規模な配列で操作され、はい、私はsel_idを再利用します。 – CJLam

+0

上記の私の解決策が間違っていることが分かりました。それが10個の1の配列であれば、与えられたコードは5個の1の配列の代わりにNone配列を返します。 – CJLam

答えて

10

、私は実際にブールマスクを使用したい:

a = numpy.arange(10) 
include_index = numpy.arange(4) 
include_idx = set(include_index) #Set is more efficient, but doesn't reorder your elements if that is desireable 
mask = numpy.array([(i in include_idx) for i in xrange(len(a))]) 

今すぐあなたの値を取得することができます:a[mask]は必ずしも同じでは得られないことを

included = a[mask] # array([0, 1, 2, 3]) 
excluded = a[~mask] # array([4, 5, 6, 7, 8, 9]) 

注意をそのようなシナリオでの出力のためには、include_indexの順番が重要であるため(a[sorted(include_index)]とおおよそ等しくなるはずです)、a[include_index]のようなものです。ただし、除外されたアイテムの順序は明確に定義されていないため、これが正常に機能するはずです。


EDIT

マスクを作成するための良い方法は次のとおりです。

mask = np.zeros(a.shape,dtype=bool) 
mask[include_idx] = True 

(セバーグのおかげで)

+0

何が問題なのかについてコメントを残すことを選択した場合、この回答が持つ可能性がある問題を解決してもよろしいですか? – mgilson

+0

@BiRico - 間違っています。 'include_index'をO(1)に入る' __contains__'メソッドを持つ 'set'(' include_idx'と呼ばれる)に変換しました。この解は 'O(N)'の複雑さを持っています。 – mgilson

+0

+1これはほぼ正確に私が提案しようとしていたものですが、私はコンピュータから離れなければなりませんでした。ブール値マスクを使用すると、相対的な補数を計算するために余分な作業をする必要がないため、このような操作に適しています。ちょうどfyiで、list comprehensionに 'array'の代わりに' fromiter'をジェネレータで使用すると、私のテストによれば、スピードが少し向上します。 – senderle

-1

numpy.setdiff1d(a, a[sel_id])トリックを行う必要があります。これ以上のものがあるかどうかは分かりません。

+0

配列に繰り返し値がある場合、それは機能しません。 – reptilicus

2

それはより多くのようなものだ:残りの部分を選択するための構文:彼らは[N]の連続使用している場合、また

a = numpy.array([1, 2, 3, 4, 5, 6, 7, 4]) 
exclude_index = numpy.arange(5) 
include_index = numpy.setdiff1d(numpy.arange(len(a)), exclude_index) 
a[include_index] 
# array([6, 7, 4]) 

# Notice this is a little different from 
numpy.setdiff1d(a, a[exclude_index]) 
# array([6, 7] 
0

。たとえば、arr [5:]は配列の最後から5番目の要素を選択します。この単純な1次元の場合については

+0

もしそうでなければ? –

4

あなたはブールマスクとうまくこれを行うことができます(@mgilsonから撮影)

a = numpy.arange(10) 

mask = np.ones(len(a), dtype=bool) # all elements included/True. 
mask[[7,2,8]] = False    # Set unwanted elements to False 

print a[mask] 
# Gives (removing entries 7, 2 and 8): 
[0 1 3 4 5 6 9] 

追加。作成されたバイナリマスクは、a[~mask]で元のスライスを戻すのにうまく使用できますが、元のインデックスがの場合はになります。


EDIT:私はこの時(2012年9月)でnp.deleteバギーを検討することを実現しなければならなかったとして、下に移動。

また、マスクはより強力です(そして、将来はOKオプションでなければならないと思いますが)np.deleteを使用することもできます。しかし、現時点では上記の方が遅く、負のインデックス(またはスライスが与えられたときのステップ)で予期しない結果が発生します。

print np.delete(a, [7,2,8]) 
+1

はい - 2番目のアプローチはこれまでのところ最高で、唯一の純粋なnumpy線形apprach ...振り返って明らかです! (舞台裏では、 'numpy.delete'は[setdiff1d'](https://github.com/numpy/numpy/blob/master/numpy/lib/function_base.py#L3380)を使用します。 ['in1d'](https://github.com/numpy/numpy/blob/master/numpy/lib/arraysetops.py#L384)。これもn log nです。)+1はできますが、すでに私のものがあります! – senderle

+0

@senderle真剣に! That funny、多分 'np.delete'はその実行パスに変更を使うことができます... – seberg

+1

-1で 'np.delete'を使用します。 **決して**良いアイデアはありません。 –

-1

aが1次元配列であると仮定すると、あなただけのインデックスのリストから、あなたがしたくない項目をポップできます

accept = [i for i in range(a.size) if i not in avoid_list] 
a[accept] 

また

のようなものを使用することを試みることができます
accept = sorted(set(range(a.size)) - set(indices_to_discard)) 
a[accept] 

アイデアは、必要のないインデックスセットの補完的なインデックス付けを使用することです。

1

私はブールマスクでこれを行いますが、少し異なります。 N次元で作業することの利点は、連続的であってもなくてもよい。メモリ使用量は、マスクされた配列に対してビューまたはコピーが作成されたかどうかによって決まりますが、わかりません。

import numpy 
a = numpy.arange(10) 
sel_id = numpy.arange(5) 
mask = numpy.ma.make_mask_none(a.shape) 
mask[sel_id] = True 
answer = numpy.ma.masked_array(a, mask).compressed() 
print answer 
# [5 6 7 8 9] 
+0

マスクされた配列は本当に良いオプションかもしれません。 '.compressed()'はマスクされた配列目的のIMOを幾分打ち負かしますが、これは通常の配列コピーを作成するためです。 – seberg

+0

合意しましたが、問題は配列の残りの部分を取得することでした... –

関連する問題