从给定的numpy数组[1,2,3,4]和窗口wz = 2(前两个元素和每个元素后面的两个元素)我必须得到对(中心el,el来自窗口)。具有未存在元素的对可以被跳过或替换为零。所以在这个例子中我必须得到这个:
[[1., 0.]
[2., 1.]
[3., 2.]
[4., 3.]
[1., 2.]
[2., 3.]
[3., 4.]
[4., 0.]
[1., 0.]
[2., 0.]
[3., 1.]
[4., 2.]
[1., 3.]
[2., 4.]
[3., 0.]
[4., 0.]]
我的实施非常低效,看起来像:
x = np.array([1,2,3,4])
l = x.shape[0]
for i in range(1, m):
init = np.empty((x.shape[0]*2,2))
init[:,0] = np.append(x, x)
init[:l,1] = np.pad(x, (i,0), mode='constant')[:l]
init[-l:,1] = np.pad(x, (0,i), mode='constant')[-l:]
corpus.extend(init)
有人可以提供更高效的解决方案吗? 在另一个我已实现的简单测试数据和变体上:
285 µs ± 19.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
379 µs ± 7.68 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
答案 0 :(得分:2)
这是一种Numpythonic方法:
In [23]: a = np.array([1,2,3,4])
In [24]: arr = np.hstack((a-1, a+1, a - 2, a+ 2))
In [25]: mask = ~np.in1d(arr, a)
In [26]: arr[mask] = 0
In [27]: np.column_stack((np.tile(a, 4), arr))
Out[27]:
array([ [1, 0],
[2, 1],
[3, 2],
[4, 3],
[1, 2],
[2, 3],
[3, 4],
[4, 0],
[1, 0],
[2, 0],
[3, 1],
[4, 2],
[1, 3],
[2, 4],
[3, 0],
[4, 0]])
答案 1 :(得分:1)
如果LineBorder
是某些数据,例如字词或随机值,我们需要重新组合,我们可以在x
中使用reindexing mechanism。
由零版本替换
numpy
让我们构建索引矩阵。
x = np.array([1,2,3,4])
wz = 2
zero = 0
输出:
ri = np.arange(-wz,wz+1)+np.arange(x.shape[0]).reshape(-1,1)
print(ri)
现在,如果我们将 [[-2, -1, 0, 1, 2],
[-1, 0, 1, 2, 3],
[ 0, 1, 2, 3, 4],
[ 1, 2, 3, 4, 5]
作为最后一个元素添加零,我们可以用索引替换错误的索引。
x
输出:
np.place(ri,(ri<0)|(ri>x.shape[0]),x.shape[0]) #replace wrong indexes
np.vstack((
np.hstack((x,[zero]))[ri].reshape(1,-1),#extending x with zero and reindexing
np.tile(x,2*wz+1)) #repeating basic `x` to each window position
)#.T #uncomment .T to make it vertical
跳过的版本
同样的想法,但顺序略有不同:产生一个完整的索引矩阵 ([[0, 0, 1, 2, 3, 0, 1, 2, 3, 4, 1, 2, 3, 4, 0, 2, 3, 4, 0, 0],
[1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]])
然后排除错误的对,最后重新索引'x'。
[window_index,x_index]
输出:
x = np.array([1,2,3,4])
wz = 2
ri = np.vstack((
(np.arange(-wz,wz+1)+np.arange(x.shape[0]).reshape(-1,1)).ravel(),#same index matrix flaten
np.tile(np.arange(x.shape[0]),2*wz+1) #repeating `x` indexes to each window position
))
x[ri[:,(ri[0]>=0)&(ri[0]<x.shape[0])]]#.T #uncomment .T to make it vertical
更新1 (错误修复) 从窗口中排除零以避免配对重复。
[[1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4, 2, 3, 4],
[3, 4, 1, 3, 4, 1, 2, 3, 4, 1, 2, 4, 1, 2]]
输出:
x = np.array([1,2,3,4])
wz = 2
ri = np.vstack(((
np.hstack(( np.arange(-wz,0), #remove zero from window
np.arange(1,wz+1)))+
np.arange(x.shape[0]).reshape(-1,1)).ravel(), #same index matrix flaten
np.tile(np.arange(x.shape[0]),2*wz) #repeating `x` indexes to each window position
))
x[ri[:,(ri[0]>=0)&(ri[0]<x.shape[0])]]#.T #uncomment .T to make it vertical
检查使用过的功能np.arange,np.reshape,np.place,np.hstack,broadcasting rules和indexing的文档。
答案 2 :(得分:0)
numpy方法是有利的,但对于那些感兴趣的人来说,这是一种功能性的方法:
<强>鉴于强>
changeClickFunction() {
if( this.favoriteID ) {
this.functionAddress = this.unsetFavorite;
} else {
this.functionAddress = this.setFavorite;
}
}
<强>代码强>
import functools as ft
# Helper function
def curry(f):
@ft.wraps(f)
def wrapped(arg):
try:
return f(arg)
except TypeError:
return curry(ft.wraps(f)(ft.partial(f, arg)))
return wrapped
输出
lst = [1, 2, 3, 4]
c = curry(lambda x, y: x + y)
funcs = [c(-1), c(1), c(-2), c(2)]
set_ = set(lst)
[[x, 0] if fn(x) not in set_ else [x, fn(x)] for fn in funcs for x in lst]
<强>详情
在列表推导的双[[1, 0],
[2, 1],
[3, 2],
[4, 3],
[1, 2],
[2, 3],
[3, 4],
[4, 0],
[1, 0],
[2, 0],
[3, 1],
[4, 2],
[1, 3],
[2, 4],
[3, 0],
[4, 0]]
循环中,迭代curried函数列表,并将每个函数应用于主列表的每个元素(for
)。 Currying允许您通过传入一些参数(例如lst
)并稍后从主列表传入元素来计算新值。
创建了元组,例如(主要元素,计算元素)。列表推导的条件部分用1, -1, -2, 2
替换在主列表中找不到的计算元素。