如何优雅地“重构”numpy数组

2024-04-24 20:46:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用numpy.array作为数据缓冲区,并且我正在寻找一种优雅的方法来reframe,这样它就可以根据新的帧条件保留一部分初始数据(该缓冲区可能有shrunkexpandedshifted或{}或两者的组合)

Reframe在这里可能不是合适的术语。但希望下面的例子能说明:

为了简单起见,我将使用False来演示一个空的reframed数组元素:

import numpy as np

# Init buffer
data = 10 * np.arange(6) + 10 # dummy data for this example
# Result: array([10, 20, 30, 40, 50, 60]) # 

缩小缓冲区:

^{pr2}$

扩展缓冲区:

# shift start by 2 to the left, and end by 1 to the 
reframe(data,-2,1)
# Desired Result: array([False, False, 10, 20, 30, 40, 50, 60, False]) # 

向左或向右移动缓冲区+展开:

# shift start by 2 to the right, and end by 4 to the right 
reframe(data,2,4)
# Desired Result: array([30, 40, 50, 60, False, False, False, False]) # 

在这个例子中,我再次使用了False,其中我希望有一个新的空reframed数组元素。这可以是np.empty,或者{},等等。。。在

为了实现我的目标,我写了以下内容:

import numpy as np

def reframe(data,start,end):

    # Shrinking: new array is a substet of original
    if start >= 0 and end <=0:
        if start > 0 and end < 0:
            return data[start:end]
        if start > 0:
            return data[start:]
        return data[:end]

    # Expand, new array fully contains original
    elif start <= 0 and end >= 0:
        new = np.zeros(data.shape[0] + end - start).astype(data.dtype)
        new[abs(start):data.shape[0]+2] = data
        return new

    # Shift, new array may have a portion of old
    else:
        new = np.zeros((data.shape[0]-start+end)).astype(data.dtype)

        # Shift Right
        if start > 0:
            new[:data.shape[0]-start] = data[start:]
            return new

        # Shift Left
        if end < 0:
            new[:data.shape[0]+end] = data[::-1][abs(end):]
            return new[::-1]

测试:

print reframe(data,1,-1) # [20 30 40 50]
print reframe(data,-2,1) # [ 0  0 10 20 30 40 50 60  0]
print reframe(data,2,4)  # [30 40 50 60  0  0  0  0]

所以这对我来说是可行的,但我希望有更优雅的东西。在

在我的实际应用程序中,我的阵列数十万个,所以效率是必须的。在


Tags: andtofalsenewdatabyreturnif
1条回答
网友
1楼 · 发布于 2024-04-24 20:46:06
import numpy as np

def reframe(x, start, end, default=0):
    shape = list(x.shape)
    orig_length = shape[0]
    shape[0] = length = end - start

    old_start = max(0, start)
    old_end = min(end, length + 1, orig_length)
    new_start = -start if start < 0 else 0
    new_end = new_start + old_end - old_start

    x_new = np.empty(shape, dtype=x.dtype)
    x_new[:] = default
    x_new[new_start:new_end] = x[old_start:old_end]
    return x_new

x = np.arange(6) + 1

x_new = reframe(x, 1, 4)
print('1. ', x_new)

x_new = reframe(x, -4, 4)
print('2. ', x_new)

x_new = reframe(x, 1, 7)
print('3. ', x_new)

x_new = reframe(x, -1, 9, default=4)
print('4. ', x_new)

x = np.arange(100).reshape(20, 5) + 1
x_new = reframe(x, -1, 2)
print('5. ', x_new)

输出:

^{pr2}$

我相信这符合要求。在这个问题中,我不清楚的主要部分是为什么开始是10,结束是15,而不是说0和5。此函数为0索引。start的负索引意味着您希望从开始处扩展到左侧。另外,它也不包括在内,因为python/numpy通常就是这样工作的。在

很难知道默认值应该是什么,因为我不知道数组的类型。因此,我添加了一个默认参数,它将初始化数组。在

相关问题 更多 >