![](/img/trans.png)
[英]Append inner 0 & 1st index to all elements in 2nd index two-dimensional List of Lists - python
[英]Python: Comparing all elements of two arrays and modifying 2nd array
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
我使用Numpy对'a'和'b'进行了比较,如下所示:
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)
我如何从这里开始获取'c'?
即使阵列大小不同,这些解决方案也能正常工作。
简单版
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. ])
尝试以更一般的方式更好地解释您的程序应该做什么。 只给出数组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]
顺便说一句,如果这是一个课程,你可能仍然会因为不遵守规范(“......并修改第二个数组”)而得分不好。
使用np.isclose
您已经创建了一个“最近”元素为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. ])
。
但请注意,您要设置所有不接近的元素,因此您需要反转( ~
)结果。
看来你想保留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
: in1d(a,b)
是[False, True, True, False, False]
由于True
为1
而False
为0
,因此a*in1d(a,b)
为[ 0., 5.1, 6.2, 0. , 0. ]
a*in1d(a,b)
。 [ 0., 5.1, 6.2, 0. , 0. ]
。 由于in1d
a
和b
排序,因此它是一种复杂的算法,但通常更快。 如果需要近似相等,则解决方案可以首先对数组进行舍入( np.round(a,1)
)
这是我能够获得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. ]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.