【问题标题】:python Aggregate (groupby) 2d-matrixpython聚合(groupby)二维矩阵
【发布时间】:2014-12-03 14:48:15
【问题描述】:

我有一个方阵/数据矩阵(大约 2000 行和列) 我想将它聚合成一个较小的数组(大约 1000 行和列)

我有一个 main_ids 列表,它对应于原始数组中的行/列。 例如new_ids = [0,0,0,1,1,2,...] 会将前 3 行/列聚合到新行/列 1,然后将第 4、5 行/列聚合到第 2 行,依此类推上...

到目前为止,我有以下代码,但如果可能的话,我想对其进行优化

import numpy as np
new_ids = np.array(new_ids)
unew_ids = unique(new_ids)
unew_ids.sort()

#Collapse rows
rowMat = np.zeros([len(new_ids),len(unew_ids)], dtype=np.float64)

for i in range(0,len(mat[0])):
    for j in range(0, len(unew_ids)):
        rowMat[i,j] = np.sum(mat[i][new_ids == unew_ids[j]])

#Collapse columns
outMat = np.zeros([len(unew_ids),len(unew_ids)], dtype=np.float64)

for i in range(0, len(unew_ids)):
    for j in range(0, len(unew_ids)):
        outMat[j,i] = np.sum(rowMat[:,i][new_ids == unew_ids[j]])

return outMat

我尝试过使用 matplotlib.mlab.rec_groupby,但是为此我需要(或者我认为我需要)构建一个新的 (new_ids, row) 数组,其中 row 是一个 numpy 数组,其中一行来自原始矩阵,但是这似乎不起作用。

[编辑:]

作为一个额外的问题,我在聚合时实际上并没有做求和,我正在做一个需要一次所有数字的自定义函数(按行做,然后列不起作用)

{大致 - my_function = (取元素的总和,如果有负数从总和中删除,然后将整个事物乘以 1/(1+负元素的总和))}

我认为我需要做的是:

outputmat = [ [my_function(input_mat[new_ids_arr == tuple])] for tuple in unique_arr.ravel()]

outputmat = np.array(outputmat)
outputmat.reshape(something)

其中 new_ids_arr 是 [[(10,10),(10,10),...][(10,10),(10,10),(10,12),.. 形式的数组.],...] - 即聚合后所有内容的元组。 我希望我能找到一个功能(或构建一个)来做 new_ids_arr = new_ids * new_ids^Transpose ... 或类似的

unique_arr = 是一个与输出具有相同大小/形状的数组,并且每个元素都包含一个元组(例如,unique_arr[0,0] = (10,10) 意味着将所有 input_matrix 元素放在一个地方标记为 10,10 进入此位置)。

有什么想法吗? 特别是关于如何在给定列表的情况下轻松构建元组数组?

【问题讨论】:

  • 作为一个额外的问题,我在聚合时实际上并没有进行求和,我正在做一个需要一次所有数字的自定义函数(按行然后按列来做不是工作)
  • 我认为我需要做的是:从 new_ids - 制作一个“矩阵”,其中每个元素都是一个元组指向聚合所在的位置。例如new_ids = [10,10,12,5,5,..] 然后 new_ids_mat = [[(10,10),(10,10),....],[(10,10),(12,10 ),....]..] 我想要 new_ids_mat = (new_ids * new_ids^T) 或其他东西...希望有一个我可以使用的函数.. 然后我对我的 unique_new_ids 列表做同样的事情 - [[10 ,10),(10,5),...]]。然后类似 unique_new_ids_r = unique_new_ids.ravel() output = [ [my_func(input_mat[new_ids_mat[tuple]]) ] for tuple in unique_new_ids_r] 听起来对吗?

标签: python arrays numpy matplotlib


【解决方案1】:

如果您可以将您的 new_ids 转换为 [0,3,5,...] 之类的内容,那么您可以尝试以下操作:

import numpy as np
np.random.seed(0)
arr = np.random.rand(20,20)

rowidx = np.array([0, 3, 9, 12, 18], dtype=np.int32)
colidx = np.array([0, 5, 10, 15], dtype=np.int32)

#Collapse rows
step1 = np.add.reduceat(arr, rowidx, axis=0)

#Collapse columns
step2 = np.add.reduceat(step1, colidx, axis=1)

【讨论】:

  • 谢谢,我不确定是否可以将我的 new_ids 减少到一组切片。也许。我有戏
  • 有用的信息谢谢,不幸的是我的问题需要同时聚合行和列。请参阅问题编辑。