Python新手,并且一直在学习数组。我遇到了一个简单的问题,需要一个解决方案。我有两个数组:
a = [2.0, 5.1, 6.2, 7.9, 23.0] # always increasing
b = [5.1, 5.5, 5.7, 6.2, 00.0] # also always increasing
我希望得到的数组为:
c = [0.0, 5.1, 6.2, 0.0, 0.0] # 5.5, 5.7, 00.0 from 'b' were dropped and rearranged such that position of equivalent elements as in 'a' are maintained
我比较了两个' a' &安培; ' B'使用Numpy,如:
y = np.isclose(a, b)
print y
# [False False False False False]
(或者,)我也试过这样的事情,这不是正确的方式(我认为):
c = np.zeros(len(a))
for i in range (len(a)):
for j in range (len(a)):
err = abs(a[i]-b[j])
if err == 0.0 or err < abs(1):
print (err, a[i], b[j], i, j)
else:
print (err, a[i], b[j], i, j)
如何从这里开始获取&#39; c&#39;?
答案 0 :(得分:4)
即使阵列大小不同,这些解决方案也能正常工作。
简易版
c = []
for i in a:
if any(np.isclose(i, b)):
c.append(i)
else:
c.append(0.0)
Numpy版
aa = np.tile(a, (len(b), 1))
bb = np.tile(b, (len(a), 1))
cc = np.isclose(aa, bb.T)
np.any(cc, 0)
c = np.zeros(shape=a.shape)
result = np.where(np.any(cc, 0), a, c)
说明:
我将在这里进行矩阵比较。首先,将数组扩展为矩阵。交换长度,这会产生具有相同大小的一维矩阵:
aa = np.tile(a, (len(b), 1))
bb = np.tile(b, (len(a), 1))
他们看起来像这样:
# aa
array([[ 2. , 5.1, 6.2, 7.9, 23. ],
[ 2. , 5.1, 6.2, 7.9, 23. ],
[ 2. , 5.1, 6.2, 7.9, 23. ],
[ 2. , 5.1, 6.2, 7.9, 23. ],
[ 2. , 5.1, 6.2, 7.9, 23. ]])
# bb
array([[ 5.1, 5.5, 5.7, 6.2, 0. ],
[ 5.1, 5.5, 5.7, 6.2, 0. ],
[ 5.1, 5.5, 5.7, 6.2, 0. ],
[ 5.1, 5.5, 5.7, 6.2, 0. ],
[ 5.1, 5.5, 5.7, 6.2, 0. ]])
然后比较它们。请注意,bb是转置的:
cc = np.isclose(aa, bb.T)
你得到:
array([[False, True, False, False, False],
[False, False, False, False, False],
[False, False, False, False, False],
[False, False, True, False, False],
[False, False, False, False, False]], dtype=bool)
您可以按轴0聚合:
np.any(cc, 0)
返回
array([False, True, True, False, False], dtype=bool)
现在创建数组c:
c = np.zeros(shape=a.shape)
从a或c:
中选择适当的值np.where(np.any(cc, 0), a, c)
结果:
array([ 0. , 5.1, 6.2, 0. , 0. ])
答案 1 :(得分:1)
尝试以更一般的方式更好地解释您的程序应该做什么。只给出数组a,b和c并不能告诉它应该做什么。就好像有人说“如果A = 5而B = 7,那就编写一个程序使C = 20”。
根据你的尝试,我猜测任务是“c的每个元素应该等于a的相应元素,如果它的值接近(差值为0.5或更小)与b中的相应值。如果没有,应该为零。“
另外,你真的需要使用numpy吗?尝试仅使用循环和列表方法。您还可以查看“生成器表达式和列表推导”
最后,你的标题是“(...)并修改第二个数组”。不应该有一个名为c的第三个数组。结果应出现在数组b的修改版本中。
编辑:如果规范是真的这个,那么代码可能是
a = [2.0, 5.1, 6.2, 7.9, 23.0]
b = [5.1, 5.5, 5.7, 6.2, 0.0]
c = []
for x,y in zip(a,b): c.append( x if abs(x-y)<=0.5 else 0.0 )
print c
其中给出了以下答案
[0.0, 5.1, 6.2, 0.0, 0.0]
顺便说一句,如果这是一个课程,你可能仍然会因为不遵守规范(“......并修改第二个数组”)而得分不好。
答案 2 :(得分:1)
使用np.isclose
,您已经创建了一个数组,其中&#34;最接近&#34;元素是True
。因此,您可以使用此结果将所有其他元素设置为零。
import numpy as np
a = np.array([2.0, 5.1, 6.2, 7.9, 23.0]) # always increasing
b = np.array([5.1, 5.5, 5.7, 6.2, 00.0]) # also always increasing
a[~np.isclose(a,b, atol=0.5)] = 0
a
这会返回array([ 0. , 5.1, 6.2, 0. , 0. ])
。
但请注意,您要设置所有不接近的元素,因此您需要反转(~
)结果。
答案 3 :(得分:1)
您似乎希望保留a
中同样位于b
的元素。
纯线性时间python解决方案:
c=zeros_like(a)
j=0
n=len(c)
for i in range(n):
while j<n and b[j]<a[i]-.1 : j+=1
if j==n : break
if abs(a[i]-b[j])<.1 : c[i]=a[i]
完全匹配的numpy解决方案:
a*in1d(a,b)
。
in1d(a,b)
表示a
中b
的{{1}}元素的位置:in1d(a,b)
是[False, True, True, False, False]
由于True
为1
且False
为0
,a*in1d(a,b)
为[ 0., 5.1, 6.2, 0. , 0. ]
。由于in1d
对a
和b
进行排序,因此它是一种复杂的算法,但速度通常更快。如果需要近似相等,则解决方案可以首先对数组进行舍入(np.round(a,1)
)
答案 4 :(得分:0)
这是我能够获得c所需安排的替代方式。
import numpy as np
a = [2.0, 5.1, 6.2, 7.9, 23.0] # always increasing
b = [5.1, 5.5, 5.7, 6.2, 00.0] # also always increasing
c = np.zeros(len(a))
for i in range (len(a)):
for j in range (len(a)):
err = abs(a[i]-b[j])
if err == 0.0 or err < abs(0.1):
c[i] = b[j]
print c
#[ 0. 5.1 6.2 0. 0. ]