1

大きな (たとえば、4000 X 4000) numpy な float の行列を作成しました。行列のセルをフロート値で並べ替え、(row,col,value)タプルのリストを作成しています。これは私のコードです(簡略化):

def cells(matrix):
  shape = np.shape(matrix)
  for row in range(shape[0]):
    for col in range(shape[1]):
      yield (row, col, matrix[row,col])

# create a random matrix
matrix = np.random.randint(100, size=(4000,4000))
# sort the cells by value
sorted_cells = sorted(cells(matrix), key=lambda x: x[2])

セルごとの利回りを行うのは非効率的であることは承知していますが(row, col, value)、純粋なnumpyを使用してマトリックスのタプルを反復する方法がわかりませんか? 多分それは本当の質問です!

私の現在のアプローチの問題は、並べ替えの段階でコンピューターが完全に死んでしまうことです。

私がそうしても問題ありません:sorted(matrix.flatten())実際には非常に高速に動作しますが、行と列を取得できません...

4

2 に答える 2

7

numpy.argsortはここであなたの友達です。指定された配列を実際に並べ替える代わりに、配列を並べ替えて並べ替える方法を示す整数インデックスの配列を返します。そのため、行と列の値に同じ並べ替えを適用できます。

以下にいくつかのコードを示します。まず行列を生成します。ここでは、結果が正しい方法であることを簡単に確認できるように、さまざまな数の行と列を使用しています。

>>> import numpy as np
>>> matrix = np.random.randint(100, size=(4000, 5000))
>>> rows, cols = np.indices(matrix.shape)

argsortインデックスを取得するために使用します。

>>> reindex = np.argsort(matrix.flatten())

これらのインデックスを使用して、並べ替えられた行列を復元できます。

>>> matrix.flat[reindex]
array([ 0,  0,  0, ..., 99, 99, 99])

また、対応する行と列。

>>> rows.flat[reindex]
array([2455, 2870, 1196, ...,   56,   56, 3618])
>>> cols.flat[reindex]
array([ 863, 1091, 4966, ..., 3959, 3887, 4833])

0答えを確認するために、最初の行と列のペアが実際に の行列エントリに対応し、最後の行と列のペアが に対応することを確認しましょう99

>>> r = rows.flat[reindex]
>>> c = cols.flat[reindex]
>>> matrix[r[0], c[0]]
0
>>> matrix[r[-1], c[-1]]
99

編集:nye17の回答が指摘しているように、行と列はreindex配列からより直接的に復元できます。

>>> r, c = divmod(reindex, matrix.shape[1])

これはすべて非常に迅速に実行されます (並べ替えのステップに数秒かかります)。元のコードがマシンをロックしている理由は、生成しているリストが多くのメモリを占有しているためだと思います。リストやタプルの代わりに numpy 配列を使用することで、メモリのオーバーヘッドが大幅に削減されます。

于 2012-06-29T19:21:07.397 に答える
2

マークはパンチで私を打ち負かしますが、私の2セントだけです

例として 2x2 マトリックスを使用し、

import numpy as np
# create a random matrix
matrix = np.random.randint(100, size=(2,2))
indice = np.argsort(matrix, axis=None)
# you can also use `divmod` per mark's version
ind_i = indice//2
ind_j = np.mod(indice, 2)
for i, j in zip(ind_i, ind_j) :
    print("%4d %4d %10.5f" % (i, j, matrix[i,j]))

それは与えます

1    0   12.00000
0    1   23.00000
1    1   59.00000
0    0   63.00000
于 2012-06-29T19:26:04.213 に答える