我有一个向量y2
,可以递增或递减1.我想要的是创建另一个向量y1
,显示numpy
何时改变方向。
我无法在import matplotlib.pyplot as plt
import numpy as np
中找出如何执行此操作。
由于y
中缺少逗号,编辑了更新的情节import matplotlib.pyplot as plt
import numpy as np
y = np.array([0,0,1,1,2,2,1,0,-1,-1,0,0,1])
x = np.arange(len(y))
y2 = np.array([0,0,1,0,0,0,-1,0,0,0,1,0,0])
plt.plot(x, y, label='y - Actual')
plt.plot(x, y2, label='y2 - Desired')
plt.legend()
plt.show()
编辑:已修复y中缺少的逗号
{{1}}
答案 0 :(得分:2)
编辑:现在还处理超出规格的输入(增量在-1,0,1之外)。
这里的速度稍快(暂时)(pp是我,D是@Divakar):
# n = 10
# pp 0.02363790 ms
# D 0.03705720 ms
# n = 1000
# pp 0.03609150 ms
# D 0.05877410 ms
# n = 1000000
# pp 22.63471480 ms
# D 36.92147740 ms
包括基准测试的代码:
import numpy as np
import types
from timeit import timeit
def setup_data(n, allow_out_of_spec=True):
if allow_out_of_spec:
data = {'y': np.cumsum(np.random.randint(0, 10, (n,))
* np.random.randint(-1, 2, (n,)))}
else:
data = {'y': np.cumsum(np.random.randint(-1, 2, (n,)))}
return data
# mine
def f_pp(y, allow_out_of_spec=True):
if allow_out_of_spec:
d = np.sign(np.diff(y))
else:
d = np.diff(y)
ud = np.flatnonzero(d)
uds = d[ud]
chng = ud[np.r_[True, uds[1:] != uds[:-1]]]
out = np.zeros(len(y), dtype=int)
out[1:][chng] = d[chng]
return out
# @Divakar's
def f_D(y):
s0 = np.flatnonzero(y[1:] > y[:-1])+1
s1 = np.flatnonzero(y[1:] < y[:-1])+1
idx0 = np.searchsorted(s1,s0,'right')
s0c = s0[np.r_[True,idx0[1:] > idx0[:-1]]]
idx1 = np.searchsorted(s0c,s1,'right')
s1c = s1[np.r_[True,idx1[1:] > idx1[:-1]]]
out = np.zeros(len(y),dtype=int)
out[s0c] = 1
out[s1c] = -1
return out
for n in (10, 1000, 1000000):
data = setup_data(n)
ref = np.array(f_pp(**data))
print(f'n = {n}')
for name, func in list(globals().items()):
if not name.startswith('f_') or not isinstance(func, types.FunctionType):
continue
try:
assert np.allclose(ref, func(**data))
print("{:16s}{:16.8f} ms".format(name[2:], timeit(
'f(**data)', globals={'f':func, 'data':data}, number=10)*100))
except:
print("{:16s} apparently failed".format(name[2:]))
答案 1 :(得分:1)
这是一种方式 -
def detect_ups_downs(y):
s0 = np.flatnonzero(y[1:] > y[:-1])+1
s1 = np.flatnonzero(y[1:] < y[:-1])+1
idx0 = np.searchsorted(s1,s0,'right')
s0c = s0[np.r_[True,idx0[1:] > idx0[:-1]]]
idx1 = np.searchsorted(s0c,s1,'right')
s1c = s1[np.r_[True,idx1[1:] > idx1[:-1]]]
out = np.zeros(len(y),dtype=int)
out[s0c] = 1
out[s1c] = -1
return out
示例运行 -
In [92]: y = np.array([0,0,1,2,3,4,1,0,-1-1,0,0,1,0,8,8,9,-4,-6,4,-2,2])
In [93]: np.c_[y, detect_ups_downs(y)]
Out[93]:
array([[ 0, 0],
[ 0, 0],
[ 1, 1],
[ 2, 0],
[ 3, 0],
[ 4, 0],
[ 1, -1],
[ 0, 0],
[-2, 0],
[ 0, 1],
[ 0, 0],
[ 1, 0],
[ 0, -1],
[ 8, 1],
[ 8, 0],
[ 9, 0],
[-4, -1],
[-6, 0],
[ 4, 1],
[-2, -1],
[ 2, 1]])
答案 2 :(得分:-1)
尝试采用衍生物:
dy = y[1:] - y[:-1]
然后检查相邻点是否已切换衍生符号:
increasing = dy > 0
decreasing = dy < 0
saddle = dy == 0
change_increasing = increasing[1:] and decreasing[:-1]
change_decreasing = decreasing[1:] and increasing[:-1]
将所有信息汇集在一起:
changes = np.zeros_like(dy)
changes[0] = (1 * increasing[0]) + (-1 * decreasing[0])
changes[1:][change_increasing] = 1
changes[1:][change_decreasing] = -1
changes[saddle] = 0
print(changes)