Python 寻找矩阵大对角线下的所有元素

Python 寻找矩阵大对角线下的所有元素,python,matrix,Python,Matrix,我有如下矩阵: matrix = [ ['a', 'p', 'p', 'l', 'e'], ['a', 'g', 'o', 'd', 'o'], ['n', 'n', 'e', 'r', 't'], ['g', 'a', 'T', 'A', 'C'], ['m', 'i', 'c', 's', 'r'], ['P', 'o', 'P', 'o', 'P']] 我试图找到大对角线下的所有元素。但我希望他们以某种方式, 例如,理想的输出是: ["ocAt", "PsC","or","P"] (我

我有如下矩阵:

matrix = [
['a', 'p', 'p', 'l', 'e'],
['a', 'g', 'o', 'd', 'o'],
['n', 'n', 'e', 'r', 't'],
['g', 'a', 'T', 'A', 'C'],
['m', 'i', 'c', 's', 'r'],
['P', 'o', 'P', 'o', 'P']]
我试图找到大对角线下的所有元素。但我希望他们以某种方式, 例如,理想的输出是:

["ocAt", "PsC","or","P"]
(我想要字母以“向右方上升的对角线”的方式,这里的大对角线是“PiTro”)

我试过这样的方法:

    for f in range(len(matrix) - 1, -1, -1):
      for k in range(len(matrix)-1, 0, -1):
        my_list.append(matrix[k][k-f])
但是我要么得到一个超出范围的索引,要么不是好的元素。
如果有人有解决办法,我很高兴知道

这是实现该结果的一种方法:

matrix = [['a', 'p', 'p', 'l', 'e'],
          ['a', 'g', 'o', 'd', 'o'],
          ['n', 'n', 'e', 'r', 't'],
          ['g', 'a', 'T', 'A', 'C'],
          ['m', 'i', 'c', 's', 'r'],
          ['P', 'o', 'P', 'o', 'P']]
my_list = []
for f in range(1, len(matrix[0])):
    s = []
    for k in range(len(matrix[0]) - f):
        s.append(matrix[len(matrix) - k - 1][f + k])
    my_list.append(''.join(s))
print(my_list)
# ['ocAt', 'PsC', 'or', 'P']
或使用理解:

my_list = [''.join(matrix[len(matrix) - i - 1][j + i] for i in range(len(matrix[0]) - j))
           for j in range(1, len(matrix[0]))]

要生成每个对角线中的每个子字符串,可以执行以下操作:

my_list = []
for j in range(1, len(matrix[0])):
    for i1 in range(0, len(matrix[0]) - j):
        for i2 in range(i1 + 1, len(matrix[0]) - j + 1):
            s = []
            for i in range(i1, i2):
                s.append(matrix[len(matrix) - i - 1][j + i])
            my_list.append(''.join(s))
print(my_list)
# ['o', 'oc', 'ocA', 'ocAt', 'c', 'cA', 'cAt', 'A', 'At', 't', 'P', 'Ps', 'PsC', 's', 'sC', 'C', 'o', 'or', 'r', 'P']
或相当于:

my_list = [''.join(matrix[len(matrix) - i - 1][j + i] for i in range(i1, i2))
           for j in range(1, len(matrix[0]))
           for i1 in range(0, len(matrix[0]) - j)
           for i2 in range(i1 + 1, len(matrix[0]) - j + 1)]
--

上对角线中的子字符串的一种解决方案:

my_list = []
for i in range(len(matrix)):
    for j1 in range(min(i + 1, len(matrix[0]))):
        for j2 in range(j1, min(i + 1, len(matrix[0]))):
            s = []
            for j in range(j1, j2 + 1):
                s.append(matrix[i - j][j])
            my_list.append(''.join(s))
print(my_list)
# ['a', 'a', 'ap', 'p', 'n', 'ng', 'ngp', 'g', 'gp', 'p', 'g',
#  'gn', 'gno', 'gnol', 'n', 'no', 'nol', 'o', 'ol', 'l', 'm',
#  'ma', 'mae', 'maed', 'maede', 'a', 'ae', 'aed', 'aede', 'e',
#  'ed', 'ede', 'd', 'de', 'e', 'P', 'Pi', 'PiT', 'PiTr', 'PiTro',
#  'i', 'iT', 'iTr', 'iTro', 'T', 'Tr', 'Tro', 'r', 'ro', 'o']
其他方法:

width = len(matrix[0])
height =len(matrix)
result = [''] * (width-1)

number_elements_to_take = width-1
for row in reversed(matrix):
    i = 0
    for element in row[width - number_elements_to_take:]:
        result[i] += element
        i+=1
    number_elements_to_take -= 1

使用
numpy

matrix = numpy.array([['a', 'p', 'p', 'l', 'e'],
                      ['a', 'g', 'o', 'd', 'o'],
                      ['n', 'n', 'e', 'r', 't'],
                      ['g', 'a', 'T', 'A', 'C'],
                      ['m', 'i', 'c', 's', 'r'],
                      ['P', 'o', 'P', 'o', 'P']])

result_list = [''.join(numpy.flipud(matrix[i:,i:]).diagonal())
               for i in range(1, len(matrix)-1)]

另一个使用
跟踪的NumPy解决方案

列表(映射(np.flipud(np.array(matrix,object))。跟踪,范围(1,len(matrix)-1))) ['ocAt','PsC','or','P']
Related:
numpy.flipud(matrix).diagonal(i)
应该比
numpy.flipud(matrix[i:,i:]).diagonal()好,而且您不需要将其转换为
np.array
@Sayandip Dutta:实际上这会让它慢一点,因为这会在每次迭代中翻转整个矩阵。在理解列表之前翻转一次会更好。我做了一些测试,恰恰相反。我认为在每个循环中对两个维度进行切片都很昂贵。但性能差异可以忽略不计。对于1000次迭代:使用切片:
0.01560
不使用切片:
0.01482
。在我的机器上,速度较慢,26us(
np.flipud(矩阵)。对角线(i)
)比11.5us(
np.flipud(矩阵[i:,i:])。对角线()。(切片比分配新阵列的成本更低。)
umatrix.diagonal(i)
如果事先翻转
umatrix
,它将降低到6.16us。