Assuming A as an input array, several methods are listed below.
Approach # 1: Using np.triu for transposed version A -
np.triu(AT,1) + A
Approach # 2: Avoid np.triu with direct summation between AT and A and then indexing to set diagonal elements -
out = AT + A idx = np.arange(A.shape[0]) out[idx,idx] = A[idx,idx]
Approach No. 3: The same as the previous one, but compact using the built-in constructions for indexing -
out = AT + A np.fill_diagonal(out,np.diag(A))
Approach # 4: Same as previous, but with boolean indexing to set diagonal elements -
out = AT + A mask = np.eye(out.shape[0],dtype=bool) out[mask] = A[mask]
Approach # 5: Using mask-based selections for diagonal elements with np.where -
np.where(np.eye(A.shape[0],dtype=bool),A,A.T+A)
Approach # 6: Using mask selection for all elements with np.where -
np.where(np.triu(np.ones(A.shape[0],dtype=bool),1),AT,A)
Runtime tests
Functions -
def func1(A): return np.triu(AT,1) + A def func2(A): out = AT + A idx = np.arange(A.shape[0]) out[idx,idx] = A[idx,idx] return out def func3(A): out = AT + A np.fill_diagonal(out,np.diag(A)) return out def func4(A): out = AT + A mask = np.eye(out.shape[0],dtype=bool) out[mask] = A[mask] return out def func5(A): return np.where(np.eye(A.shape[0],dtype=bool),A,A.T+A) def func6(A): return np.where(np.triu(np.ones(A.shape[0],dtype=bool),1),AT,A)
Dates -
In [140]:
Looks like approaches # 2 and # 3 are pretty effective!