Python:如何将任意数量的小矩阵动态组合成一个大矩阵
我有这4个矩阵,我想通过传递n:小矩阵的数量和输出矩阵的行和列,动态地将它们组合成一个大矩阵 例如: 输出矩阵:Python:如何将任意数量的小矩阵动态组合成一个大矩阵,python,numpy,matrix,Python,Numpy,Matrix,我有这4个矩阵,我想通过传递n:小矩阵的数量和输出矩阵的行和列,动态地将它们组合成一个大矩阵 例如: 输出矩阵: [[ 1 2 5 6] [ 3 4 7 8] [ 9 10 13 14] [11 12 15 16]] 我可以使用以下工具手动执行此操作: M = np.bmat( [[x1], [x2], [x3], [x4]] ) 2分钟实施(对于编辑前的问题,可能对某人有用): 如果阵列的大小很大,则有改进的余地…2分钟的实施时间(对于编辑前的问题,可能对某些人有用):
[[ 1 2 5 6]
[ 3 4 7 8]
[ 9 10 13 14]
[11 12 15 16]]
我可以使用以下工具手动执行此操作:
M = np.bmat( [[x1], [x2], [x3], [x4]] )
2分钟实施(对于编辑前的问题,可能对某人有用):
如果阵列的大小很大,则有改进的余地…2分钟的实施时间(对于编辑前的问题,可能对某些人有用):
如果数组的大小很大,那么还有改进的余地……我认为(但不知道它是否正确),最好是原地工作,避免每次都用新方法创建新对象,特别是在循环中多次创建时。这些示例仅适用于二维矩阵。但它可以很容易地实现到更多维度。最好是有一个大数组,如果它真的很大的话,用numpy.memmap数组。然后在它的部分工作。最快的索引(仅次于指针)将出现在cython MemoryView上
import numpy as np
def combine_matrix(*args):
n=len(args)
rows,cols=args[0].shape
a=np.zeros((n,cols*rows))
m=0
for i in range(n/rows):
for j in range(n/cols):
a[i*rows:(i+1)*rows,j*cols:(j+1)*cols]=args[m]
m+=1
return a
def example1():
print '#'*10
a=np.arange(1,17)
n=4
rows,cols=n/2,n/2
lst=[]
for i in range(n):
ai=a[i*n:(i+1)*n]
ai.shape=rows,cols
lst.append(ai)
print lst
print combine_matrix(*lst)
def example2():
print '#'*10
m=24
a=np.arange(m)
n=6
rows,cols=m/n/2,n/2
lst=[]
for i in range(m/n):
ai=a[i*n:(i+1)*n]
ai.shape=rows,cols
lst.append(ai)
print lst
print combine_matrix(*lst)
def example3():
print '#'*10
m,n=36,6
a=np.arange(m)
arrs=np.array_split(a,n)
for i in range(n):
ln=arrs[i].shape[0]
arrs[i].shape=2,ln/2
print combine_matrix(*arrs)
example1()
example2()
example3()
我认为(但不知道是否正确),最好是原地工作,避免每次都用新方法创建新对象,特别是在循环中多次创建新对象时。这些示例仅适用于二维矩阵。但它可以很容易地实现到更多维度。最好是有一个大数组,如果它真的很大的话,用numpy.memmap数组。然后在它的部分工作。最快的索引(仅次于指针)将出现在cython MemoryView上
import numpy as np
def combine_matrix(*args):
n=len(args)
rows,cols=args[0].shape
a=np.zeros((n,cols*rows))
m=0
for i in range(n/rows):
for j in range(n/cols):
a[i*rows:(i+1)*rows,j*cols:(j+1)*cols]=args[m]
m+=1
return a
def example1():
print '#'*10
a=np.arange(1,17)
n=4
rows,cols=n/2,n/2
lst=[]
for i in range(n):
ai=a[i*n:(i+1)*n]
ai.shape=rows,cols
lst.append(ai)
print lst
print combine_matrix(*lst)
def example2():
print '#'*10
m=24
a=np.arange(m)
n=6
rows,cols=m/n/2,n/2
lst=[]
for i in range(m/n):
ai=a[i*n:(i+1)*n]
ai.shape=rows,cols
lst.append(ai)
print lst
print combine_matrix(*lst)
def example3():
print '#'*10
m,n=36,6
a=np.arange(m)
arrs=np.array_split(a,n)
for i in range(n):
ln=arrs[i].shape[0]
arrs[i].shape=2,ln/2
print combine_matrix(*arrs)
example1()
example2()
example3()
[编辑-我假设小数组是独立创建的,尽管我的示例是基于拆分(4,2,2)数组。如果它们实际上只是3d数组的平面,则“重塑”和“转置”的组合会更好。但即使这样的解决方案也会生成副本,因为原始值已重新排列。] 让我们列出2x2阵列(此处来自3d阵列)。需要挤压,因为此拆分生成(1,2,2)阵列: 您的
bmat
方法-已更正以生成方形排列
In [333]: np.bmat([[xl[0],xl[1]],[xl[2],xl[3]]])
Out[333]:
matrix([[ 1, 2, 5, 6],
[ 3, 4, 7, 8],
[ 9, 10, 13, 14],
[11, 12, 15, 16]])
串联方法:
In [334]: np.vstack([np.hstack(xl[:2]),np.hstack(xl[2:])])
Out[334]:
array([[ 1, 2, 5, 6],
[ 3, 4, 7, 8],
[ 9, 10, 13, 14],
[11, 12, 15, 16]])
由于切片在hstack
中工作,我也可以在bmat
中使用它:
In [335]: np.bmat([xl[:2],xl[2:]])
Out[335]:
matrix([[ 1, 2, 5, 6],
[ 3, 4, 7, 8],
[ 9, 10, 13, 14],
[11, 12, 15, 16]])
内部bmat
(检查其代码)正在使用hstack
的vstack
版本(第一个和最后一个轴上的ContactEnables)。有效地
In [366]: ll=[xl[:2], xl[2:]]
In [367]: np.vstack([np.hstack(row) for row in ll])
Out[367]:
array([[ 1, 2, 5, 6],
[ 3, 4, 7, 8],
[ 9, 10, 13, 14],
[11, 12, 15, 16]])
您必须如何指定这些n
数组的排列np.bmat(xl)
生成一个(2,8)
矩阵(hstack
)<代码>np.vstack(xl)生成一个(8,2)
数组
将其扩展到3x3、2x3等子阵列布局应该不难xl
是子阵列的列表。将其重新加工为所需的子阵列列表,并应用bmat
或堆栈的组合
2个2x3布局的快速版本(4dxl
阵列比2x3嵌套列表更容易构建,但功能相同:
In [369]: xl=np.arange(3*2*2*2).reshape((3,2,2,2))
In [370]: np.vstack([np.hstack(row) for row in xl])
Out[370]:
array([[ 0, 1, 4, 5],
[ 2, 3, 6, 7],
[ 8, 9, 12, 13],
[10, 11, 14, 15],
[16, 17, 20, 21],
[18, 19, 22, 23]])
In [371]: xl=np.arange(2*3*2*2).reshape((2,3,2,2))
In [372]: np.vstack([np.hstack(row) for row in xl])
Out[372]:
array([[ 0, 1, 4, 5, 8, 9],
[ 2, 3, 6, 7, 10, 11],
[12, 13, 16, 17, 20, 21],
[14, 15, 18, 19, 22, 23]])
[编辑-我假设小数组是独立创建的,尽管我的示例是基于拆分(4,2,2)数组。如果它们实际上只是3d数组的平面,则“重塑”和“转置”的组合会更好。但即使这样的解决方案也会生成副本,因为原始值已重新排列。]
让我们列出2x2阵列(此处来自3d阵列)。需要挤压,因为此拆分会生成(1,2,2)阵列:
您的bmat
方法-已更正以生成方形排列
In [333]: np.bmat([[xl[0],xl[1]],[xl[2],xl[3]]])
Out[333]:
matrix([[ 1, 2, 5, 6],
[ 3, 4, 7, 8],
[ 9, 10, 13, 14],
[11, 12, 15, 16]])
串联方法:
In [334]: np.vstack([np.hstack(xl[:2]),np.hstack(xl[2:])])
Out[334]:
array([[ 1, 2, 5, 6],
[ 3, 4, 7, 8],
[ 9, 10, 13, 14],
[11, 12, 15, 16]])
由于切片在hstack
中工作,我也可以在bmat
中使用它:
In [335]: np.bmat([xl[:2],xl[2:]])
Out[335]:
matrix([[ 1, 2, 5, 6],
[ 3, 4, 7, 8],
[ 9, 10, 13, 14],
[11, 12, 15, 16]])
内部bmat
(检查其代码)正在使用hstack
的vstack
版本(第一轴和最后一轴上的触点)。有效
In [366]: ll=[xl[:2], xl[2:]]
In [367]: np.vstack([np.hstack(row) for row in ll])
Out[367]:
array([[ 1, 2, 5, 6],
[ 3, 4, 7, 8],
[ 9, 10, 13, 14],
[11, 12, 15, 16]])
您必须如何指定这些n
数组的排列。np.bmat(xl)
生成(2,8)
矩阵(hstack
)。np.vstack(xl)
生成(8,2)
数组
将其扩展到3x3、2x3等子阵列布局应该不难。xl
是子阵列列表。将其重新编辑为所需的子阵列列表,并应用bmat
或堆栈的组合
2个2x3布局的快速版本(4dxl
阵列比2x3嵌套列表更容易构建,但功能相同:
In [369]: xl=np.arange(3*2*2*2).reshape((3,2,2,2))
In [370]: np.vstack([np.hstack(row) for row in xl])
Out[370]:
array([[ 0, 1, 4, 5],
[ 2, 3, 6, 7],
[ 8, 9, 12, 13],
[10, 11, 14, 15],
[16, 17, 20, 21],
[18, 19, 22, 23]])
In [371]: xl=np.arange(2*3*2*2).reshape((2,3,2,2))
In [372]: np.vstack([np.hstack(row) for row in xl])
Out[372]:
array([[ 0, 1, 4, 5, 8, 9],
[ 2, 3, 6, 7, 10, 11],
[12, 13, 16, 17, 20, 21],
[14, 15, 18, 19, 22, 23]])
您可以将换位和重塑操作结合起来:
In [1878]: x=arange(24).reshape(4,3,2)
In [1879]: (_,n,m)=x.shape
In [1880]: x.reshape(2,2,n,m).transpose(0,2,1,3).reshape(2*n,2*m)
Out[1880]:
array([[ 0, 1, 6, 7],
[ 2, 3, 8, 9],
[ 4, 5, 10, 11],
[12, 13, 18, 19],
[14, 15, 20, 21],
[16, 17, 22, 23]])
您可以将换位和重塑操作结合起来:
In [1878]: x=arange(24).reshape(4,3,2)
In [1879]: (_,n,m)=x.shape
In [1880]: x.reshape(2,2,n,m).transpose(0,2,1,3).reshape(2*n,2*m)
Out[1880]:
array([[ 0, 1, 6, 7],
[ 2, 3, 8, 9],
[ 4, 5, 10, 11],
[12, 13, 18, 19],
[14, 15, 20, 21],
[16, 17, 22, 23]])
如果你想知道bmat是如何工作的,你需要澄清这些小数组是单独创建的,还是只是3d数组的平面。你是从(4,2,2)数组开始,然后将其转换成(4,4)数组吗数组,或者从4个单独的数组开始。你对bmat
没有提供的数组有什么要求?如果你想知道bmat是如何工作的,你需要澄清这些小数组是单独创建的,还是它们只是3d数组的平面。你是从(4,2,2)数组开始并将其转换为(4,4)数组吗数组,或从4个单独的数组开始。anserw用于在新anserw中编辑;转储我的2分钟解决方案xDanserw用于在新anserw中编辑是浪费;转储我的2分钟解决方案xDanserw是浪费。如果每次创建新列表并使用方法,我不喜欢它。在cython MemoryView上,更快的解决方案不是就位了吗?您的答案是t像串联
,除了你的操作在两个轴上。如果用c或cython编码,你的可以在我重复的堆栈上节省时间。列表副本没有什么大不了的,因为它们只是复制对象指针。如果原始数组还没有占用