我有两个数组命名u,v, e.g。
u=np.array([1.0,2.0,2.0,3.0,4.0])
v=np.array([10.0,21.0,18.0,30.0,40.0])
a=np.array([100.0,210.0,220.0,300.0,400.0])
如果u中的两个元素相同,则删除v值较高的元素。 对于上面的例子,结果应该是
u_new=np.array([1.0,2.0,3.0,4.0])
v_new=np.array([10.0,18.0,30.0,40.0])
a_new=np.array([100.0,220.0,300.0,400.0])
def remove_duplicates(u,v,a):
u_new, indices = np.unique(u, return_index=True)
v_new = np.zeros(len(u_new), dtype=np.float64)
a_new = np.zeros(len(u_new), dtype=np.float64)
for i in range(len(indices)):
j1 = indices[i]
if i < len(indices) - 1:
j2 = indices[i + 1]
else:
j2 = j1 + 1
v_new[i] = np.amin(v[j1:j2])
k = np.argmin(v[j1:j2]) + j1
a_new[i] = a[k]
return u_new,v_new,a_new
上面的代码在处理浮点数时有问题,因为两个浮点数之间没有完全相等。因此,我必须将其改为非常'愚蠢'的方式
def remove_duplicates(u, v, a):
u_new=u
v_new=v
a_new=a
cnt = 0
for i in range(len(u)):
if cnt <1:
u_new[cnt] = u[i]
v_new[cnt] = v[i]
a_new[cnt] = a[i]
cnt += 1
else:
if abs(u[i]-u_new[cnt-1]) > 1e-5:
u_new[cnt] = u[i]
v_new[cnt] = v[i]
a_new[cnt] = a[i]
cnt += 1
else:
print("Two points with same x coord found.ignore", i)
if v_new[cnt-1] > v[i]:
v_new[cnt-1] = v[i]
a_new[cnt-1] = a[i]
return u_new[:cnt], v_new[:cnt], a_new[:cnt]
如何以Pythonic方式编程? 谢谢。
答案 0 :(得分:1)
您可以使用zip
,sorted
和groupby
函数:
from itertools import groupby
u1, v1 = zip(*[next(g) for k, g in groupby(sorted(zip(u, v)), key = lambda x: x[0])])
# note here use next to take the first element(smaller v value) from each group
u1
# (1.0, 2.0, 3.0, 4.0)
v1
# (10.2, 22.0, 28.0, 41.0)
答案 1 :(得分:1)
方法#1:以下是通过分割成可容忍的(通过给定的容差值)邻近组来浮点数的方法 -
<input type="checkbox" [(ngModel)]="isChecked">
<select [(ngModel)]="selectedItem" [enabled]="!isChecked"
示例输入,输出 -
tol = 1e-5 # Set tolerance for floating pt number match
A = np.split( v, np.flatnonzero(np.diff(u) > tol)+1)
lens = np.array(list(map(len,A)))
idx = np.array([np.argmax(i) for i in A])
idx[1:] += lens[:-1].cumsum()
m = ~np.in1d(np.arange(a.size), idx[lens>1])
u_new, v_new, a_new = u[m], v[m], a[m]
方法#2:这是另一种不分裂的方法,因此效率必须更高 -
In [143]: u=np.array([1.0,2.0,2.00000001,3.0,3.9999998, 4.0, 4.00000001])
...: v=np.array([10.0,21.0,18.0,30.0,36.0, 40.0, 38.0])
...: a=np.array([100.0,210.0,220.0,300.0,77.0, 400.0, 67.00])
...:
In [144]: u_new
Out[144]: array([ 1. , 2.00000001, 3. , 3.9999998 , 4.00000001])
In [145]: v_new
Out[145]: array([ 10., 18., 30., 36., 38.])
In [146]: a_new
Out[146]: array([ 100., 220., 300., 77., 67.])
答案 2 :(得分:1)
有点厚颜无耻地改变你的问题,但现在就去了。
def remove_duplicates(u,v,a,d=1e-5):
s=np.argsort(u)
ud=abs(u[s][1:]-u[s][:-1])<d
vd=v[s][1:]<v[s][:-1]
drop=np.union1d(s[:-1][ud&vd],s[1:][ud&~vd])
return np.delete(u,drop),np.delete(v,drop),np.delete(a,drop)
这应该用一个阈值来清理你的花车。