Python 计算由前两列中的索引分组的numpy数组项的第n列之和?

Python 计算由前两列中的索引分组的numpy数组项的第n列之和?,python,numpy,loops,matrix,nested,Python,Numpy,Loops,Matrix,Nested,我想循环检查以下矩阵,以便代码识别第一个和第二个元素是1和1还是1和2等?然后,对于成对的每个单独类别,即1,1或1,2或2,2,代码应存储在新矩阵中,最后一个元素(在这种情况下具有索引8)乘以exp(-i*q(检查矩阵[k][2:5]-检查矩阵[k][5:8]),其中i是iota(复数),k是校验矩阵上的运行索引,q是定义如下的向量。因此有20个q向量 将numpy导入为np q=[] 对于np.linspace(0,10,20)中的i: q、 追加(np.array((0,0,i))) q=

我想循环检查以下
矩阵
,以便代码识别第一个和第二个元素是
1
1
还是
1
2
等?然后,对于成对的每个单独类别,即
1,1
1,2
2,2
,代码应存储在新矩阵中,最后一个元素(在这种情况下具有索引8)乘以
exp(-i*q(检查矩阵[k][2:5]-检查矩阵[k][5:8])
,其中
i
是iota(复数),
k
是校验矩阵上的运行索引,
q
是定义如下的向量。因此有20个
q
向量

将numpy导入为np
q=[]
对于np.linspace(0,10,20)中的i:
q、 追加(np.array((0,0,i)))
q=np.数组(q)
检查矩阵=np.数组([[1,1,0,0,0,0,0,0,-0.7977,-0.243293],
[1, 1, 0, 0, 0, 0,    0,       1.5954,  0.004567],
[1, 2, 0, 0, 0, -1,   0,       0,       1.126557],
[2, 1, 0, 0, 0, 0.5,  0.86603, 1.5954,  0.038934],
[2, 1, 0, 0, 0, 2,    0,       -0.7977, -0.015192],
[2, 2, 0, 0, 0, -0.5, 0.86603, 1.5954,  0.21394]])
这意味着原则上我必须有20个2x2形状的矩阵,对应于每个
q
向量

目前,我的代码只给出了一个矩阵,这似乎是最后一个矩阵,尽管我在
矩阵中追加了
。我的代码如下所示

for i in range(2):
    i = i+1
    for j in range(2):
        j= j +1
        j_list = []
        Matrices = []
        for k in range(len(check_matrix)):
            if check_matrix[k][0] == i and check_matrix[k][1] == j:
                j_list.append(check_matrix[k][8]*np.exp(-1J*np.dot(q,(np.subtract(check_matrix[k][2:5],check_matrix[k][5:8])))))
                j_11 = np.sum(j_list)
                I_matrix[i-1][j-1] = j_11
                Matrices.append(I_matrix)
I_矩阵定义如下:

I_matrix= np.zeros((2,2),dtype=np.complex_)
目前,我得到以下输出

Matrices = [array([[-0.66071446-0.77603624j, -0.29038112+2.34855023j],         [-0.31387562-0.08116629j,  4.2788    +0.j        ]])]
但是,我希望得到一个对应于每个
q
值的矩阵,这意味着在这种情况下总共应该有20个矩阵,其中每个2x2矩阵元素将包含和,使得元素以以下方式属于1,1和1,2以及2,2对

 array([[11., 12.],
       [21., 22.]])

我将非常感谢你提出的改正建议。提前谢谢

我很确定你可以用一种更简单的方式解决这个问题,我也不是100%确定我是否正确理解了你的意思,但这里有一些代码可以满足你的需要。如果您有可能检查结果是否有效,我建议您这样做

将numpy导入为np
n=20
q=np.零((20,3))
q[:,-1]=np.linspace(0,10,n)
检查矩阵=np.数组([[1,1,0,0,0,0,0,0,-0.7977,-0.243293],
[1, 1, 0, 0, 0, 0,    0,       1.5954,  0.004567],
[1, 2, 0, 0, 0, -1,   0,       0,       1.126557],
[2, 1, 0, 0, 0, 0.5,  0.86603, 1.5954,  0.038934],
[2, 1, 0, 0, 0, 2,    0,       -0.7977, -0.015192],
[2, 2, 0, 0, 0, -0.5, 0.86603, 1.5954,  0.21394]])
检查矩阵[:,:2]=1#python索引是基于零的
矩阵=np.零((n,2,2),数据类型=np.复数)
对于范围(2)中的i:
对于范围(2)内的j:
k_列表=[]
对于范围内的k(len(检查矩阵)):
如果检查矩阵[k][0]==i和检查矩阵[k][1]==j:
k_列表.追加(检查矩阵[k][8]*
np.exp(-1J*np.dot(q,校验矩阵[k][2:5]
-检查(矩阵[k][5:8]))
矩阵[:,i,j]=np.sum(k_列表,轴=0)
注意:我更改了您的索引,使其具有一致性 零基索引


这里是另一种方法,我用矢量版本替换了k循环:

for i in range(2):
    for j in range(2):
        k = np.logical_and(check_matrix[:, 0] == i, check_matrix[:, 1] == j)
        temp = np.dot(check_matrix[k, 2:5] - check_matrix[k, 5:8], q[:, :, np.newaxis])[..., 0]
        temp = check_matrix[k, 8:] * np.exp(-1J * temp)
        matrices[:, i, j] = np.sum(temp, axis=0)


3线解决方案

您在原始标题中要求提供高效的解决方案,那么这个解决方案如何避免嵌套循环和3行程序中的if语句,从而希望更快

fac=2*(check_matrix[:,0]-1)+(check_matrix[:,1]-1)
grp=np.split(check_matrix[:,8], np.cumsum(np.unique(fac,return_counts=True)[1])[:-1])
[np.sum(x) for x in grp]
输出:

[-0.23872600000000002, 1.126557, 0.023742000000000003, 0.21394]
它是如何工作的?

我将前两列合并成一个索引,将每一列视为“位”(即基数2)

(如果索引超过2,仍然可以使用此技术,但需要使用不同的基数来组合列。即,如果索引从1到18,则需要将列0乘以等于或大于18的数字,而不是2。)

所以第一行的结果是

array([0., 0., 1., 2., 2., 3.])
还要注意的是,它假设数据是有序的,一列的变化最快,如果不是这样,则需要额外的步骤对索引和原始检查矩阵进行排序。在您的示例中,数据是有序的

下一步根据索引对数据进行分组

i、 e.根据fac分组输出校验矩阵第8列


然后最后一行简单地求和这些。。。了解前两列如何组合以生成单个索引可以让您将结果映射回来。或者,如果需要的话,您可以简单地将其添加到第9列来检查矩阵。

如何最终得到第一个元素为(1,1)(1,2)的矩阵,依此类推?也许,如果您使用更智能的索引/重塑,您不必以如此复杂的方式检索信息!和
q_1
df_矩阵
I_矩阵
缺失,请提供运行代码的所有信息。感谢您的回复。我做了一些小改动,这些改动是只存在
q
,而不存在
qu 1
。没有
df_矩阵
。现在定义了
I_矩阵
。我仍然想知道如何获得
check_矩阵
,以及您在这里计算的是什么,这对我来说似乎不太复杂。好吧,check矩阵是数据的一小部分,我从另一个代码中获得的。我打算对我的数据进行傅里叶变换。你尝试过我建议的3线性吗?我认为这些建议很好,可以适当地存储数据,但我想知道如何根据每个
q
值查看20个矩阵。非常感谢。我尝试了第一个版本,即没有矢量化的版本,我实现了
array([0., 0., 1., 2., 2., 3.])
np.split(check_matrix[:,8], np.cumsum(np.unique(fac,return_counts=True)[1])[:-1])

[array([-0.243293,  0.004567]), array([1.126557]), array([ 0.038934, -0.015192]), array([0.21394])]