2017-12-05 5 views
1

나는 다음과 같은 한 :numpy - 여러 행렬 3x3 및 100x100x3 배열?

import numpy as np 

XYZ_to_sRGB_mat_D50 = np.asarray([ 
    [3.1338561, -1.6168667, -0.4906146], 
    [-0.9787684, 1.9161415, 0.0334540], 
    [0.0719453, -0.2289914, 1.4052427], 
]) 

XYZ_1 = np.asarray([0.25, 0.4, 0.1]) 
XYZ_2 = np.random.rand(100,100,3) 

np.matmul(XYZ_to_sRGB_mat_D50, XYZ_1) # valid operation 
np.matmul(XYZ_to_sRGB_mat_D50, XYZ_2) # makes no sense mathematically 

가 어떻게 XYZ_2에 그 나는 것 XYZ_2에서 동일한 작업을 수행합니까? 어떻게 든 배열을 먼저 변형합니까?

답변

2

그것은 당신이 XYZ_2(axis=2)의 마지막으로 sum-reduceXYZ_to_sRGB_mat_D50(axis=1)의 마지막 축하려고하는 것 같다. 그래서, 당신과 같이 np.tensordot을 사용할 수 있습니다 -

np.tensordot(XYZ_2, XYZ_to_sRGB_mat_D50, axes=((2),(1))) 

Related post to understand tensordot합니다.


완전성을 위해, 우리는 확실히 너무과 같이, XYZ_2의 마지막 두 축 swappping 후 np.matmul을 사용할 수 있습니다 -

np.matmul(XYZ_to_sRGB_mat_D50, XYZ_2.swapaxes(1,2)).swapaxes(1,2) 

tensordot 한만큼 효율적되지 않습니다.


런타임 테스트 - 그것은 텐서에 sum-reductions에 올 때

In [158]: XYZ_to_sRGB_mat_D50 = np.asarray([ 
    ...:  [3.1338561, -1.6168667, -0.4906146], 
    ...:  [-0.9787684, 1.9161415, 0.0334540], 
    ...:  [0.0719453, -0.2289914, 1.4052427], 
    ...: ]) 
    ...: 
    ...: XYZ_1 = np.asarray([0.25, 0.4, 0.1]) 
    ...: XYZ_2 = np.random.rand(100,100,3) 

# @Julien's soln 
In [159]: %timeit XYZ_2.dot(XYZ_to_sRGB_mat_D50.T) 
1000 loops, best of 3: 450 µs per loop 

In [160]: %timeit np.tensordot(XYZ_2, XYZ_to_sRGB_mat_D50, axes=((2),(1))) 
10000 loops, best of 3: 73.1 µs per loop 

는 일반적으로 말하기는 tensordot 훨씬 더 효율적입니다. sum-reduction 축은 단지 하나이기 때문에 배열을 재구성하여 배열을 만들 수 있습니다. np.dot을 사용하고 결과를 얻은 다음 3D으로 다시 바꿉니다.

+0

감사합니다. -이 대답은 우수합니다. 텐 소도 트가 속도를 내림에 따라 여기에서 트랜스 포즈를하는 규칙적인 점을 능가하는 것은 흥미 롭습니다. –

+0

@BrandonDube 제 생각에 tensors는'dot '이 어떤 레벨 (대부분 C 레벨)에서 루핑을하는 반면,'tensordot'는 그것을 피할 수 있습니다. – Divakar

+0

와우! 그걸 몰랐어! 모양을 바꾸는 것이 왜 10 배 빨라 졌는지에 대한 통찰력이 있습니까? 그건 말이 안되는 것 같아요. – Julien

1

당신은 아마 단순히이 원하는 :

XYZ_2.dot(XYZ_to_sRGB_mat_D50.T) 

np.matmul(XYZ_to_sRGB_mat_D50, XYZ_1)하는 XYZ_1.dot(XYZ_to_sRGB_mat_D50.T) 동일합니다, 당신은 단순히 100 × 100 × 3 행렬의 연산을 방송 할 수있다.