有没有一种快速的方法来构建numpy/pandas对角矩阵

jmo0nnb3  于 2023-04-30  发布在  其他
关注(0)|答案(2)|浏览(101)

好的,我有一个系统数组= np。array([ 1,3,1,7,1,15,1,7,1,3,1],dtype=np.int8)
我想知道是否有更快的方法来构建下面的dataframe或numpy矩阵,而不是我现在使用的公式:

systems = np.array([ 1,  3,  1,  7,  1, 15,  1,  7,  1,  3, 1], dtype=np.int8)            
                                                                                                                                    
def buildsystem(system):  
  firstrow = [0]   
  sysbuild = pd.DataFrame()  
  for y in range(len(system)):   
    firstrow.append(system[y] ^ firstrow[y])   
  sysbuild[0] = firstrow  
  for y in range(1,len(system)+1):  
    sysbuild[y] = system[y-1] ^ sysbuild[y-1]  
  return sysbuild 

h= buildsystem(systems)

In [145]: h                                                                                                                                                                       
Out[145]: 
    0   1   2   3   4   5   6   7   8   9   10  11
0    0   1   2   3   4   5  10  11  12  13  14  15
1    1   0   3   2   5   4  11  10  13  12  15  14
2    2   3   0   1   6   7   8   9  14  15  12  13
3    3   2   1   0   7   6   9   8  15  14  13  12
4    4   5   6   7   0   1  14  15   8   9  10  11
5    5   4   7   6   1   0  15  14   9   8  11  10
6   10  11   8   9  14  15   0   1   6   7   4   5
7   11  10   9   8  15  14   1   0   7   6   5   4
8   12  13  14  15   8   9   6   7   0   1   2   3
9   13  12  15  14   9   8   7   6   1   0   3   2
10  14  15  12  13  10  11   4   5   2   3   0   1
11  15  14  13  12  11  10   5   4   3   2   1   0

np.diagonal(h, 1)

In [144]: np.diagonal(h, 1)                                                                                                                                                       
Out[144]: array([ 1,  3,  1,  7,  1, 15,  1,  7,  1,  3,  1])

你会注意到systems和np完全一样。对角线
有没有更快的方法来实现这一点。我将使用最多64的int大小,并想要一个更快的方法来查找这些。任何帮助将不胜感激。您会注意到构建系统没有使用numpy或pandas函数
谢谢你

1hdlvixo

1hdlvixo1#

不要使用循环,你可以用bitwise_xoraccumulate版本和广播来构建你的输出:

firstrow = np.bitwise_xor.accumulate(np.r_[0, systems])

out = firstrow[:,None]^firstrow

print(out)
  • 注意:对于DataFrame:out = pd.DataFrame(firstrow[:,None]^firstrow ) .*

输出:

[[ 0  1  2  3  4  5 10 11 12 13 14 15]
 [ 1  0  3  2  5  4 11 10 13 12 15 14]
 [ 2  3  0  1  6  7  8  9 14 15 12 13]
 [ 3  2  1  0  7  6  9  8 15 14 13 12]
 [ 4  5  6  7  0  1 14 15  8  9 10 11]
 [ 5  4  7  6  1  0 15 14  9  8 11 10]
 [10 11  8  9 14 15  0  1  6  7  4  5]
 [11 10  9  8 15 14  1  0  7  6  5  4]
 [12 13 14 15  8  9  6  7  0  1  2  3]
 [13 12 15 14  9  8  7  6  1  0  3  2]
 [14 15 12 13 10 11  4  5  2  3  0  1]
 [15 14 13 12 11 10  5  4  3  2  1  0]]
7ivaypg9

7ivaypg92#

这是我的解决方案

import numpy as np
import pandas as pd
systems = np.array([ 1,  3,  1,  7,  1, 15,  1,  7,  1,  3, 1], dtype=np.int8)            
                                                                                                                                    
def buildsystem(system):  
  firstrow = [0]   
  for y in range(len(system)):
    firstrow.append(system[y] ^ firstrow[y])
  sysbuild = [firstrow]
  for y in range(1,len(system)+1):
    sysbuild.append(system[y-1] ^ sysbuild[y-1])
  return np.array(sysbuild) #or pd.DataFrame
   
h = buildsystem(systems)

作为一般规则,向numpy数组或pandas Dataframe 中追加/插入是相当昂贵的。最好是尽可能多地处理更简单的数据结构,如列表,并且只在最后进行转换。甚至转换本身也相当快。
我只是改写了你的函数,以避免插入到一个 Dataframe 。如果有可能用滚动/滑动技巧完全重写函数来处理递归问题,我不会感到惊讶,但现在什么也没有想到

相关问题