numpy数组的和行,其中每个和的起始索引来自另一个数组

时间:2015-05-19 03:22:44

标签: python numpy

我有一个名为NxM的{​​{1}} numpy数组。 我还有一个名为data的{​​{1}}长度数组。 我想要一个新的长度N数组,其中第i个元素是start_indices

以下是一种方法:

M

是否有更多的numpythonic方式?

3 个答案:

答案 0 :(得分:6)

您可以创建一个蒙版数组

>>> mask = start_indices[:,None] <= np.arange(data.shape[1])
>>> (data * mask).sum(axis=1)
array([  6.,  18.,  21.])

对于最后一步,您也可以使用np.einsum

>>> np.einsum('ij,ij->i', data, mask)
array([  6.,  18.,  21.])

虽然在这里使用掩码数组可能效率低下并且迭代了太多索引。

或者,np.fromiter

>>> it = (r[i:].sum() for r, i in zip(data, start_indices))
>>> np.fromiter(it, data.dtype)
array([  6.,  18.,  21.])

答案 1 :(得分:2)

除了zip迭代(几种形式)和蒙面总和之外,cumsum可能值得测试

data[:,::-1].cumsum(axis=1)[range(data.shape[0]), data.shape[1]-1-start_indices]

正确轴上的cumsum很容易;大部分表达式用于提取所需的总和。

在这个小例子中,它比zip迭代更快,但比蒙面总和慢。但排名可能随着规模而变化。

我不认为这些替代方案更多的是pythonic&#39;。他们还使用批准的Python方法。避免zip迭代的那些可能会获得numpy布朗尼点,但前提是它们在重要的地方提高速度。

np.reduceat承诺更快的速度(第一次削减,而不是一般化):

np.add.reduceat(data.ravel(),[0,4,5,8,10])[::2]

这是一个测试表达式,并没有考虑生成indices列表所需的时间

indices = np.array([0,4,4,8,8]); indices[::2] += start_indices

答案 2 :(得分:0)

DELIMITER $$
ALTER FUNCTION Tepat(tgl_permohonan DATETIME, total_hari_kerja INT)
    RETURNS INT WITH EXECUTE AS CALL AS BEGIN
    DECLARE jumlah_hari INT, i INT, selisih INT;
    SET i = 0;
    SET jumlah_hari = 0;
    WHILE (i < total_hari_kerja) 
    BEGIN 
    IF (EXTRACT(WEEK FROM tgl_permohonan) != 6) AND (EXTRACT(WEEK FROM tgl_permohonan) != 5)
    BEGIN
        SET i = i + 1;
    END IF;
    SET jumlah_hari = jumlah_hari + 1;
    SET tgl_permohonan = DATE_ADD(tgl_permohonan, INTERVAL 1 DAY);
    END;
    SET selisih = DATEDIFF(tgl_permohonan, NOW());
    IF selisih <= 0
    BEGIN
    SET selisih = 0;
    END IF;
    RETURN selisih;
    END; $$
DELIMITER ;