Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将一维阵列转换为下三角矩阵_Python_Python 3.x_Numpy - Fatal编程技术网

Python 将一维阵列转换为下三角矩阵

Python 将一维阵列转换为下三角矩阵,python,python-3.x,numpy,Python,Python 3.x,Numpy,我想把一维数组转换成一个更低的零对角矩阵,同时保留所有的数字 我知道numpy.tril函数,但它用零替换了一些元素。我需要展开矩阵以包含所有原始数字 例如: [10,20,40,46,33,14,12,46,52,30,59,18,11,22,30,2,11,58,22,72,12] 应该是 0 10 0 20 40 0 46 33 14 0 12 46 52 30 0 59 18 11 22 30 0 2 11 58 22 72 12 0 由于输入数组保存了填充下对角线位置所需的所有值,这

我想把一维数组转换成一个更低的零对角矩阵,同时保留所有的数字

我知道
numpy.tril
函数,但它用零替换了一些元素。我需要展开矩阵以包含所有原始数字

例如:

[10,20,40,46,33,14,12,46,52,30,59,18,11,22,30,2,11,58,22,72,12]

应该是

0
10 0
20 40 0
46 33 14 0
12 46 52 30 0
59 18 11 22 30 0
2 11 58 22 72 12 0

由于输入数组保存了填充下对角线位置所需的所有值,这里有一种方法是使用
掩蔽
-

def fill_lower_diag(a):
    n = int(np.sqrt(len(a)*2))+1
    mask = np.tri(n,dtype=bool, k=-1) # or np.arange(n)[:,None] > np.arange(n)
    out = np.zeros((n,n),dtype=int)
    out[mask] = a
    return out
样本运行-

In [82]: a
Out[82]: 
array([10, 20, 40, 46, 33, 14, 12, 46, 52, 30, 59, 18, 11, 22, 30,  2, 11,
       58, 22, 72, 12])

In [83]: fill_lower_diag(a)
Out[83]: 
array([[ 0,  0,  0,  0,  0,  0,  0],
       [10,  0,  0,  0,  0,  0,  0],
       [20, 40,  0,  0,  0,  0,  0],
       [46, 33, 14,  0,  0,  0,  0],
       [12, 46, 52, 30,  0,  0,  0],
       [59, 18, 11, 22, 30,  0,  0],
       [ 2, 11, 58, 22, 72, 12,  0]])
具有
5k x 5k
形状的大型阵列上的计时-

In [146]: np.random.seed(0)

In [147]: n = 5000

In [148]: a = np.random.randint(0,9,n*(n+1)/2)

In [149]: %timeit tril_indices_app(a) #@Brenlla's solution
1 loop, best of 3: 218 ms per loop

In [151]: %timeit fill_lower_diag(a) # From this post
10 loops, best of 3: 43.1 ms per loop

您还可以使用numpy函数:

生成零矩阵并用值填充下半部分:

idx = np.tril_indices(n, k=-1, m=n)
matrix = np.zeros((n,n)).astype(int)
matrix[idx] = arr
array([[ 0,  0,  0,  0,  0,  0,  0],
       [10,  0,  0,  0,  0,  0,  0],
       [20, 40,  0,  0,  0,  0,  0],
       [46, 33, 14,  0,  0,  0,  0],
       [12, 46, 52, 30,  0,  0,  0],
       [59, 18, 11, 22, 30,  0,  0],
       [ 2, 11, 58, 22, 72, 12,  0]])

您也可以尝试下面的函数来获取列表

import pprint

def get_triangled_list(l, rows, typ='lower'):
    if type(l) is not list:
        print 'First parameter should be a list'
        return None

    if type(rows) is not int:
        print 'Second parameter should be a list'
        return None

    if not(typ == 'lower' or typ == 'upper'):
        print 'ERROR:', typ, 'is not allowed type'
        return None

    new_l = []
    length = len(l)
    num_items = ((rows-1) * rows)/ 2

    if length != num_items:
        print 'ERROR: ', 'There should be exactly', num_items, 'items for ', rows, 'rows, found', length, 'items.'
        return None

    if typ == 'upper':
        for i in range(rows):
            temp_l = [0]*(i+1) + [l.pop(0) for j in range(7-(i+1))] 
            new_l.append(temp_l)
    elif typ=='lower':
        for i in range(rows):
            temp_l = [l.pop(0) for j in range(i)] + [0]*(rows-i)
            new_l.append(temp_l)

    return new_l

if __name__ == '__main__':
    l = [10,20,40,46,33,14,12,46,52,30,59,18,11,22,30,2,11,58,22,72,12]

    # TEST CASE 1 (LOWER TRIANGLE, default)
    new_lower = get_triangled_list(l, 7)
    pprint.pprint(new_lower)
    print('\n')

    # TEST CASE 2 (UPPER TRIANGLE, passing one more parameter)
    l = [10,20,40,46,33,14,12,46,52,30,59,18,11,22,30,2,11,58,22,72,12]
    new_upper = get_triangled_list(l, 7, 'upper')
    pprint.pprint(new_upper)
输出»
是的,掩码索引可以更快,内存效率更高(只要您正在索引)。我的aproach仅对相对于三角形矩阵的较小
k
具有竞争力size@Brenlla我认为生成这些索引与获得显示差异的掩码也是一个问题,特别是对于大尺寸阵列。是的,这是真的。在你的计时代码中,它不应该是
n*(n-1)
?@Brella啊,是的,谢谢。它将生成5001 x 5001形状的阵列。时间不应该有太大变化。
import pprint

def get_triangled_list(l, rows, typ='lower'):
    if type(l) is not list:
        print 'First parameter should be a list'
        return None

    if type(rows) is not int:
        print 'Second parameter should be a list'
        return None

    if not(typ == 'lower' or typ == 'upper'):
        print 'ERROR:', typ, 'is not allowed type'
        return None

    new_l = []
    length = len(l)
    num_items = ((rows-1) * rows)/ 2

    if length != num_items:
        print 'ERROR: ', 'There should be exactly', num_items, 'items for ', rows, 'rows, found', length, 'items.'
        return None

    if typ == 'upper':
        for i in range(rows):
            temp_l = [0]*(i+1) + [l.pop(0) for j in range(7-(i+1))] 
            new_l.append(temp_l)
    elif typ=='lower':
        for i in range(rows):
            temp_l = [l.pop(0) for j in range(i)] + [0]*(rows-i)
            new_l.append(temp_l)

    return new_l

if __name__ == '__main__':
    l = [10,20,40,46,33,14,12,46,52,30,59,18,11,22,30,2,11,58,22,72,12]

    # TEST CASE 1 (LOWER TRIANGLE, default)
    new_lower = get_triangled_list(l, 7)
    pprint.pprint(new_lower)
    print('\n')

    # TEST CASE 2 (UPPER TRIANGLE, passing one more parameter)
    l = [10,20,40,46,33,14,12,46,52,30,59,18,11,22,30,2,11,58,22,72,12]
    new_upper = get_triangled_list(l, 7, 'upper')
    pprint.pprint(new_upper)
[[0, 0, 0, 0, 0, 0, 0],
 [10, 0, 0, 0, 0, 0, 0],
 [20, 40, 0, 0, 0, 0, 0],
 [46, 33, 14, 0, 0, 0, 0],
 [12, 46, 52, 30, 0, 0, 0],
 [59, 18, 11, 22, 30, 0, 0],
 [2, 11, 58, 22, 72, 12, 0]]


[[0, 10, 20, 40, 46, 33, 14],
 [0, 0, 12, 46, 52, 30, 59],
 [0, 0, 0, 18, 11, 22, 30],
 [0, 0, 0, 0, 2, 11, 58],
 [0, 0, 0, 0, 0, 22, 72],
 [0, 0, 0, 0, 0, 0, 12],
 [0, 0, 0, 0, 0, 0, 0]]