0

PHPでは配列の深さの問題があるため、Pythonからこの配列を受け取ると、省略記号( "...")で切り捨てられます。phpに戻る前に、Pythonで配列を処理したいと思います。

明確化:内部セットを維持する必要があります[135、121、81]。これらはR、G、Bの値であり、複数回発生するグループセットに関連付けています。セット内の値は、[1、2、3、4、5、6、7、8]ではなく、[1、2、3]シーケンスを維持する必要があります。これは、以下でいくつかの回答が示唆しているためです。

numpy.ndarrayこの3DをユニークなRGBトリプルのコレクションにどのように単純化しますか?

Pythonによる配列の出力方法は次のとおりです。

[[[135 121  81]
  [135 121  81]
  [135 121  81]
  ..., 
  [135 121  81]
  [135 121  81]
  [135 121  81]]

 [[135 121  81]
  [135 121  81]
  [135 121  81]
  ..., 
  [135 121  81]
  [135 121  81]
  [135 121  81]]

 [[ 67  68  29]
  [135 121  81]
  [ 67  68  29]
  ..., 
  [135 121  81]
  [135 121  81]
  [135 121  81]]

 ..., 
 [[200 170  19]
  [200 170  19]
  [200 170  19]
  ..., 
  [ 67  68  29]
  [ 67  68  29]
  [ 67  68  29]]

 [[200 170  19]
  [200 170  19]
  [200 170  19]
  ..., 
  [116 146  15]
  [116 146  15]
  [116 146  15]]

 [[200 170  19]
  [200 170  19]
  [200 170  19]
  ..., 
  [116 146  15]
  [116 146  15]
  [116 146  15]]]

これが私が試みたコードです:

def uniquify(arr)
    keys = []

    for c in arr:
        if not c in keys:
            keys[c] = 1
        else:
            keys[c] += 1

    return keys

result = uniquify(items)
4

4 に答える 4

3

「配列」の表現に基づいて、を使用しているように見えますnumpy.ndarray.flatその場合、これは非常に単純な問題になります。属性を使用して、1次元の反復可能な単純に変換できます。ユニークにするために、あなたはただ使用することができますset

set(array.flat)

これでセットが得られますが、リストを簡単に取得できます。

list(set(array.flat))

仕組みは次のとおりです。

>>> array = np.zeros((10,12,42,53))
>>> list(set(array.flat))
[0.0]

補足として、np.unique配列の固有の要素を提供するものもあります。

>>> array = np.zeros((10,12),dtype=int)
>>> print array
[[0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0 0 0]]
>>> np.unique(array)
array([0])
>>> array[0,5] = 1
>>> array[4,10] = 42
>>> np.unique(array)
array([ 0,  1, 42])

私はついにこれを理解したと思います:

from itertools import product

items = set(tuple(a[itr+(slice(None),)]) for itr in product(*[range(x) for x in a.shape[:-1]]))
print items

動作しているようです。ふぅ!

これがどのように機能するか-トリプレットとして保持したい部分は、次のようにアクセスされます。

array[X,Y,:]

したがって、とのすべての組み合わせをループする必要がXありYます。それはまさにitertools.product良いことです。有効な任意の数の次元Xを取得できます。Y

[range(x) for x in array.shape[:-1]]

それで、それを製品に渡します。

indices_generator = product(*[range(x) for x in array.shape[:-1]])

これで、最初のインデックスを生成するものができました-その__getitem__numpyに渡すタプルを作成するだけで、次(X,Y,:)のように解釈されます-簡単です。すでに(X,Y)indexes_generatorから取得しています-emtpyに取り組む必要がありますスライス:

all_items = ( array[idx+(slice(None),)] for idx in indices_generator )

これで、all_itemsをループして、セットを持つ一意のアイテムを探すことができます。

unique_items = set(tuple(item) for item in all_items)

次に、これをリスト、numpy配列、またはPHPに戻すために必要なものに戻します。

于 2013-01-30T02:15:15.063 に答える
1

itertoolsドキュメントのレシピを見てください。まさにあなたが望むことをする機能がありflattenます。unique_everseen

したがって、それらをコピーして貼り付けることができます。または、pip install more-itertoolsインポートするだけでもかまいません。これで、3Dアレイを2Dにフラット化し、2Dアレイをunique_everseen…で一意化できます。

1つの問題を除いて。2D配列の要素はlistsであり、ハッシュ可能ではないため、ハッシュ可能なものに変換する必要があります。しかし、それは簡単です。

def uniquify(arr3d):
    return unique_everseen(flatten(arr3d), tuple)

それでおしまい。

そして、それらを貼り付けている間にそれらの関数の実装を見ると、それらは非常に単純です。ここでの唯一の本当のトリックは、setこれまでに見た値を保持するためにを使用することです。セットは、各一意の要素の1つのコピーのみを保持します(そして、要素がすでにセットにあるかどうかを非常に迅速に判断できます)。

実際、順序を保持する必要がない場合は、さらに簡単です。

def uniquify(arr3d):
    return set(tuple(x) for x in flatten(arr3d))

テストとして、文字列をコピーして実際のPythonリスト表示に変換し、次のようにしました。

inarray = [[[135, 121, 81],
            [135, 121, 81],
            [135, 121, 81],
            [135, 121, 81],
            [135, 121, 81],
            [135, 121, 81]],
           [[135, 121, 81],
            [135, 121, 81],
            [135, 121, 81],
            [135, 121, 81],
            [135, 121, 81],
            [135, 121, 81]],
           [[67, 68, 29],
            [135, 121, 81],
            [67, 68, 29],
            [135, 121, 81],
            [135, 121, 81],
            [135, 121, 81]],
           [[200, 170, 19],
            [200, 170, 19],
            [200, 170, 19],
            [67, 68, 29],
            [67, 68, 29],
            [67, 68, 29]],
           [[200, 170, 19],
            [200, 170, 19],
            [200, 170, 19],
            [116, 146, 15],
            [116, 146, 15],
            [116, 146, 15]],
           [[200, 170, 19],
            [200, 170, 19],
            [200, 170, 19],
            [116, 146, 15],
            [116, 146, 15],
            [116, 146, 15]]]
for val in uniquify(inarray):
    print(val)

出力は次のとおりです。

[135, 121, 81]
[67, 68, 29]
[200, 170, 19]
[116, 146, 15]

それはあなたが望んでいたことですか?

のとして必要な場合は、次listのようになりますlist

array2d = list(uniquify(array3d))

setの代わりにsimpleを使用した場合unique_everseen、これらはtuplesの代わりにsになります。したがって、sのaがlist必要な場合:listlist

array2d = [list(val) for val in uniquify(array3d)]
于 2013-01-30T02:21:21.597 に答える
0

itertoolsここにあなたの友達がいます:

>>> import itertools
>>> array = [1,1,1,2,2,2,3,3,3,4,5,6,6,6]
>>> [x[0] for x in itertools.groupby(array)]
[1, 2, 3, 4, 5, 6]

例えば:

array = [[[135,121,81],
          [135,121,81],
          [135,121,81],
          [135,121,81],
          [135,121,81],
          [135,121,81]],
         [[135,121,81],
          [135,121,81],
          [135,121,81],
          [135,121,81],
          [135,121,81],
          [135,121,81]],
         [[67,68,29],
          [135,121,81],
          [67,68,29],
          [135,121,81],
          [135,121,81],
          [135,121,81]]]

import itertools

new_array = list()
for inner in array:
    new_inner = [x[0] for x in itertools.groupby(inner)]
    new_array.append(new_inner)

生産:

[ [ [135, 121, 81] ], 
  [ [135, 121, 81] ],
  [ [67, 68, 29],
    [135, 121, 81],
    [67, 68, 29],
    [135, 121, 81] ] ]

完全に一意ではありませんが、並べ替えinnerて一意のみを取得できます。

于 2013-01-30T02:10:36.257 に答える
0

Pythonが次のように見えると仮定しますlist[[[1,2,3], [4,5,6]], [[7,8,9]]]つまりlistlistintegers

mylist = [[[1,2,3], [4,5,6]], [[7,8,9]]]
items = set()
for sublist in mylist:
    for subsublist in sublist:
        for item in subsublist:
            items.add(item)

特にが必要な場合はlist、次のようにキャストできます。items = list(items)

Asetは、に似たデータ型ですがlist、重複は含まれていません。データ型の副作用setは、挿入順序が保持されないことです。これが重要な場合は、次のようなものが必要になります。

mylist = [[[1,2,3], [4,5,6]], [[7,8,9]]]
items = []
for sublist in mylist:
    for subsublist in sublist:
        for item in subsublist:
            if not item in items:
                items.add(item)

編集:あなたの編集に基づいて、あなたはおそらくこれが欲しいでしょう:

mylist = [[[1,2,3], [4,5,6]], [[7,8,9], [1,2,3]]]
items = []
for sublist in mylist:
    for item in sublist:
        if not item in items:
            items.append(item)
# items = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
于 2013-01-30T02:14:59.297 に答える