6

私は次のようなnumpy配列を持っています:

array = [0.2, 0.3, 0.4]

(このベクトルは実際にはサイズが300kの密度であり、簡単な例で説明しています)

次のようなScipyを使用して作成されたスパース対称行列:

M = [[0, 1, 2]  
     [1, 0, 1]  
     [2, 1, 0]]

(説明のために高密度として表されています。私の実際の問題では、(300k x 300k)スパース行列です)

すべての行に配列内の要素を掛けてから、列に関して同じ操作を行うことは可能ですか?

これにより、最初に次の結果になります。

M = [[0 * 0.2, 1 * 0.2, 2 * 0.2]
     [1 * 0.3, 0 * 0.3, 1 * 0.3]
     [2 * 0.4, 1 * 0.4, 0 * 0.4]]

(行は配列内の要素で乗算されています)

M = [[0, 0.2, 0.4]
     [0.3, 0, 0.3]
     [0.8, 0.4, 0]]

そして、列が乗算されます。

M = [[0 * 0.2, 0.2 * 0.3, 0.4 * 0.4]
     [0.3 * 0.2, 0 * 0.3, 0.3 * 0.4]
     [0.8 * 0.2, 0.4 * 0.3, 0 * 0.4]]

最終的に:

M = [[0, 0.06, 0.16]
     [0.06, 0, 0.12]
     [0.16, 0.12, 0]]

このスレッドで見つけた解決策を適用しようとしましたが、うまくいきませんでした。提案されたようにMのデータに配列内の要素を掛けてから、マトリックスを転置して同じ操作を適用しましたが、結果は正しくありませんでした。それでも理由がわかりません。

これを指摘するために、この操作を実行するマトリックスはやや大きく、ゼロ以外の要素が2,000万個あるため、効率が非常に重要です。

私はあなたの助けに感謝します!

編集:

ビット単位のソリューションは非常にうまく機能しました。ここでは、この操作の計算に1.72秒かかりましたが、これで問題ありません。Tnx!

4

3 に答える 3

8

一般に、ループを避け、速度と効率のために行列演算を使用する必要があります。この場合、解は単純な線形代数、より具体的には行列の乗算です。

Mの列に配列Aを掛けるには、M * diag(A)を掛けます。Mの行にAを掛けるには、diag(A)*Mを掛けます。両方を行うには:diag(A)* M * diag(A)。これは次の方法で実行できます。

numpy.dot(numpy.dot(a, m), a)

ここでのdiag(A)は、対角にAがあることを除いてすべてゼロである行列です。この行列を簡単に作成するメソッドを作成できます(例:numpy.diag()およびscipy.sparse.diags())。

これは非常に高速に実行されると思います。

于 2012-10-31T23:15:15.037 に答える
1

以下が機能するはずです。

[[x*array[i]*array[j] for j, x in enumerate(row)] for i, row in enumerate(M)]

例:

>>> array = [0.2, 0.3, 0.4]
>>> M = [[0, 1, 2], [1, 0, 1], [2, 1, 0]]
>>> [[x*array[i]*array[j] for j, x in enumerate(row)] for i, row in enumerate(M)]
[[0.0, 0.059999999999999998, 0.16000000000000003], [0.059999999999999998, 0.0, 0.12], [0.16000000000000003, 0.12, 0.0]]

浮動小数点演算の制限により、値はわずかにずれています。丸め誤差が許容できない場合は、 10進モジュールを使用してください。

于 2012-10-31T17:19:52.070 に答える
0

私はこの組み合わせを使用します:

def multiply(matrix, vector, axis):
    if axis == 1:
        val = np.repeat(array, matrix.getnnz(axis=1))
        matrix.data *= val
    else:
        matrix = matrix.multiply(vector)
    return matrix

軸が1(行で乗算)の場合、このソリューションの2番目のアプローチを複製し、軸が0(列で乗算)の場合、乗算を使用します。

インプレース結果(axis = 1)の方が効率的です。

于 2020-08-25T17:15:52.233 に答える