用零填充numpy数组的下三角形的最佳方法是什么,这样我就不必执行以下操作:
a=np.random.random((5,5))
a = np.triu(a)
因为np.triu返回副本,而不是视图。因为我正在处理大型数组,所以最好不需要列表索引。
答案 0 :(得分:12)
深入研究triu
的内部结构,您会发现它只是将输入乘以tri
的输出。
因此,您可以将数组乘以tri
:
>>> a = np.random.random((5, 5))
>>> a *= np.tri(*a.shape)
>>> a
array([[ 0.46026582, 0. , 0. , 0. , 0. ],
[ 0.76234296, 0.5298908 , 0. , 0. , 0. ],
[ 0.08797149, 0.14881991, 0.9302515 , 0. , 0. ],
[ 0.54794779, 0.36896506, 0.92901552, 0.73747726, 0. ],
[ 0.62917827, 0.61674542, 0.44999905, 0.80970863, 0.41860336]])
与triu
类似,这仍会创建第二个数组(tri
的输出),但至少它会就地执行操作。啪啪是一种捷径;考虑将您的函数基于triu
的完整版本,以获得强大的功能。但请注意,您仍然可以指定对角线:
>>> a = np.random.random((5, 5))
>>> a *= np.tri(*a.shape, k=2)
>>> a
array([[ 0.25473126, 0.70156073, 0.0973933 , 0. , 0. ],
[ 0.32859487, 0.58188318, 0.95288351, 0.85735005, 0. ],
[ 0.52591784, 0.75030515, 0.82458369, 0.55184033, 0.01341398],
[ 0.90862183, 0.33983192, 0.46321589, 0.21080121, 0.31641934],
[ 0.32322392, 0.25091433, 0.03980317, 0.29448128, 0.92288577]])
答案 1 :(得分:2)
如果速度和内存使用仍然是一个限制并且Cython可用,那么一个简短的Cython功能将完成你想要的。 这是一个为具有双精度值的C连续数组设计的工作版本。
cimport cython
@cython.boundscheck(False)
@cython.wraparound(False)
cpdef make_lower_triangular(double[:,:] A, int k):
""" Set all the entries of array A that lie above
diagonal k to 0. """
cdef int i, j
for i in range(min(A.shape[0], A.shape[0] - k)):
for j in range(max(0, i+k+1), A.shape[1]):
A[i,j] = 0.
这应该比任何涉及乘以大型临时数组的版本快得多。
答案 2 :(得分:0)
import numpy as np
n=3
A=np.zeros((n,n))
for p in range(n):
A[0,p] = p+1
if p >0 :
A[1,p]=p+3
if p >1 :
A[2,p]=p+4
从1
开始创建一个上三角矩阵