通过填充表示numpy中的不规则数组



我有一个与一些对象相关的分数的一维numpy数组scores。这些对象属于一些不相交的组,第一组中所有项目的得分为第一,第二组中所有项目的得分依次为第一,依此类推

我想创建一个二维数组,其中每行对应一个组,每个条目是其中一个项目的分数。如果所有的组都是相同的大小,我可以输入:

scores.reshape((numGroups, groupSize))

不幸的是,我的组可能大小不一。我知道numpy不支持不规则数组,但如果结果数组只是用指定的值填充每一行,使所有行长度相同,对我来说就很好了。

为了使其具体化,假设我设置了A有3个项目,B有2个项目,C有4个项目。

scores = numpy.array([f(a[0]), f(a[1]), f(a[2]), f(b[0]), f(b[1]), 
                       f(c[0]), f(c[1]), f(c[2]), f(c[3])])
rowStarts = numpy.array([0, 3, 5])
paddingValue = -1.0
scoresByGroup = groupIntoRows(scores, rowStarts, paddingValue)

scoresByGroup的期望值为:

 [[f(a[0]), f(a[1]), f(a[2]), -1.0], 
    [f(b[0]), f(b[1]), -1.0, -1.0]
    [f(c[0]), f(c[1]), f(c[2]), f(c[3])]]

是否有一些numpy函数或函数组合我可以使用创建groupIntoRows ?

背景:

  • 此操作将用于计算Theano中梯度下降算法的minibatch的损失,因此这就是为什么我需要将其保留为numpy函数的组合,如果可能的话,而不是返回到本机Python。
  • 可以假设存在已知的最大行大小
  • 被评分的原始对象是向量,评分函数是矩阵乘法,这就是为什么我们首先把事情弄平的原因。在进行矩阵乘法之前,可以将所有元素填充到最大项目集大小,但最大的集合比平均集合大小大十倍以上,因此出于速度原因,这是不可取的。

试试这个:

scores = np.random.rand(9)
row_starts = np.array([0, 3, 5])
row_ends = np.concatenate((row_starts, [len(scores)]))
lens = np.diff(row_ends)
pad_len = np.max(lens) - lens
where_to_pad = np.repeat(row_ends[1:], pad_len)
padding_value = -1.0
padded_scores = np.insert(scores, where_to_pad,
                          padding_value).reshape(-1, np.max(lens))
>>> padded_scores
array([[ 0.05878244,  0.40804443,  0.35640463, -1.        ],
       [ 0.39365072,  0.85313545, -1.        , -1.        ],
       [ 0.133687  ,  0.73651147,  0.98531828,  0.78940163]])

最新更新