我正在使用numpy.array
作为数据缓冲区,我正在寻找一种优雅的reframe
方式,以便保留一部分初始数据,具体取决于新的成帧条件(缓冲区可能包含shrunk
,expanded
,shifted
或shift
+ 2前者的组合
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]) #
缩小缓冲区:
# shift start by 1 to the right, and end by 1 to the left
reframe(data,1,-1) # basically doing: buffer[1:-1]
# Desired Result = array([20, 30, 40, 50]) #
展开缓冲区:
# 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
,或np.NaN
等等......
为了实现我的目标,我写了以下内容:
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]
所以这适用于我的目的,但我希望会有一些更优雅的东西。
同样在我的现实应用程序中,我的阵列数十万,所以效率是必须的。
答案 0 :(得分:2)
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)
输出:
1. [2 3 4]
2. [0 0 0 0 1 2 3 4]
3. [2 3 4 5 6 0]
4. [4 1 2 3 4 5 6 4 4 4]
5. [[ 0 0 0 0 0]
[ 1 2 3 4 5]
[ 6 7 8 9 10]]
我相信这符合要求。在问题中我不清楚的主要部分是为什么开始是10而结尾是15,而不是说0和5.这个函数是0索引的。启动的负索引意味着您想从头开始扩展到左侧。此外,它不具有包容性,因为这通常是python / numpy如何工作。
很难知道默认值应该是什么,因为我不知道数组的类型。因此,我添加了一个默认参数,它将初始化数组。