微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

python,将相同尺寸的numpy数组相加,不同形状的偏移量和滚动结束

如何解决python,将相同尺寸的numpy数组相加,不同形状的偏移量和滚动结束

我有 2 个 numpy 数组,想用偏移量对它们求和。 总和总是具有数组“a”的形状

a = np.array([1,1,1])
b = np.array([5,6])
sumWithRoll(a,b,offset=1)
print(a)
>> [1,6,7,1]

此外,如果数组 "b" 很长或偏移量足够大,它应该翻转数组 "a" 的末尾:

a = np.array([1,8])
sumWithRoll(a,offset=3)
print(a)
>> [8,9,7]

我需要它来合并两个循环播放的声音缓冲区,并希望获得占用更少内存的快速解决方案。

编辑: 我有一个看起来很长的解决方案:

def sumWithRoll(buffer,indata,idx):
    buffLen = len(buffer)
    dataLen = len(indata)
    if dataLen > buffLen:
        indata = indata[0:buffLen]
        dataLen = buffLen
    idx = idx % buffLen
    idx2 = (idx + dataLen) % buffLen
    if idx2 <= idx:
        idx3 = buffLen - idx
        buffer[idx:buffLen] += indata[0:idx3]                   
        buffer[0:idx2] += indata[idx3:buffLen]
    else:
        buffer[idx:idx2] += indata[:]

我希望有 Pythonic 的一两行解决方

解决方法

试试np.roll

import numpy as np


def sum_with_roll(a,b,offset=0):
    e = np.zeros(a.shape)
    e[tuple(map(slice,b.shape))] = b
    return a + np.roll(e,offset)


a = np.array([1,1,1])
b = np.array([5,6])
print(sum_with_roll(a,offset=1))

a = np.array([1,6,7,8])
print(sum_with_roll(a,offset=3))

输出:

[1. 6. 7. 1. 1.]
[8. 9. 1. 6. 7.]

对于 list 输出:

def sum_with_roll(a,b.shape))] = b
    return (a + np.roll(e,offset)).tolist()
[1.0,6.0,7.0,1.0,1.0]
[8.0,9.0,7.0]

对于 int 类型的输出:

def sum_with_roll(a,offset)).astype(int)
[1 6 7 1 1]
[8 9 1 6 7]
,

可以使用简单的模运算符来模拟滚动。

根据您想要将 ab 加在一起的位置的一些索引,它本质上只是在执行 a[indices] += b

a = np.array([1,6])
offset = 1

indices = np.arange(offset,len(b)+offset) % len(a)
a[indices] += b
# np.add.at(a,indices,b) - if you want to do the operation unbuffered

a 中的输出:

array([1,1])
a = np.array([1,8])
offset = 3

indices = np.arange(offset,len(b)+offset) % len(a)
a[indices] += b

a 中的输出:

array([8,9,7])

您也可以为此使用 np.bincount

a = np.array([1,len(b)+offset) % len(a)
np.bincount(indices,b)+a

输出:

array([8.,9.,1.,6.,7.])

遗憾的是,无法为 np.bincount 指定结果缓冲区,这会使 +a 操作过时。

编辑

如果你有兴趣让它更快,我建议将就地添加分成 2 片:

a = np.array([1,8])
offset = 3

size = len(a) - offset
s1 = slice(offset,offset + size)
s2 = slice(None,size)

size = len(b) - size
s3 = slice(None,size)
s4 = slice(size,None)

a[s1] += b[s2]
a[s3] += b[s4]

输出:

array([8,7])

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。