Python:比较两个数组的所有元素并修改第二个数组

Python:比较两个数组的所有元素并修改第二个数组,python,arrays,numpy,Python,Arrays,Numpy,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

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.zero(len(a))
对于范围内的i(len(a)):
对于范围内的j(len(a)):
err=abs(a[i]-b[j])
如果err==0.0或err

如何从这里开始获得“c”?

即使阵列大小不同,这些解决方案也可以工作

简单版

c = []

for i in a:
    if any(np.isclose(i, b)):
        c.append(i)
    else:
        c.append(0.0)
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)
Numpy版本

c = []

for i in a:
    if any(np.isclose(i, b)):
        c.append(i)
    else:
        c.append(0.0)
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的每个元素的值与b中的对应值接近(相差0.5或更小),则c的每个元素应等于a的对应元素。如果不是,则应为零。”

还有,你真的需要使用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

顺便说一句,如果这是一门课程,你仍然可能因为没有遵守规范(“…并修改第二个数组”)而得到不好的分数。

使用
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
这将返回
数组([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]
c=zero_类似(a)
j=0
n=len(c)
对于范围(n)中的i:

而j这是我获得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. ]
将numpy导入为np
a=[2.0,5.1,6.2,7.9,23.0]#一直在增加
b=[5.1,5.5,5.7,6.2,00.0]#也一直在增加
c=np.零(len(a))
对于范围内的i(len(a)):
对于范围内的j(len(a)):
err=abs(a[i]-b[j])
如果err==0.0或err
试试
y=np.isclose(a,b,atol=0.05)
。这不会影响结果。将
atol=0.5
放在
[False-True-False-False]
中,这是
c
bool-wise。我是否简单地从
a
中的
True
值位置复制元素值?或者有更好的方法吗?等效值必须在相同的指数下吗?或者
a=[5,6,7];b=[0,0,5]
给出
c=[5,0,0]
?(我不清楚您在第二个代码段中的注释。)是的,在相同的索引中使用相同的值,但由于这些值是按升序排列的(总是递增的),排序将更容易。第二段是另一种方式。你猜对了任务。我尝试交替使用循环而不是Numpy(参见第2段)。修改第二个数组是我需要做的,但我同意使用第三个数组
c
,因为它有助于暂时保持简单。提示:如果您是从python开始的,您应该坚持使用基础语言(即python文档中的“语言参考”和“库参考”)。不要尝试使用外部库(例如Numpy)。这不是一门课程。顺便说一句,我是一个数据科学爱好者,在使用不同的数据集时遇到了这个问题。数组实际上代表一个更大的数据集的列。你也可以直接使用数组索引修改
b
:范围内i的
(len(a)):b[i]=a[i]如果abs(a[i]-b[i]),我真的不认为这是为了一门课程:这样做的人通常会逐字粘贴家庭作业。我写这篇文章是为了强调这样一个事实:编写程序的第一步(不管你用什么语言编写程序)首先要对要完成的任务有一个清晰的概念。我认为这就是OP想要的。但他现在补充了一条评论,称
b
数组末尾可能有尾随的垃圾值,必须忽略。因此,在使用该阵列之前,需要对其进行修剪,或者调整算法。(我想这适用于所有当前的答案。)是的,我已经添加了一条关于这个假设的评论。如有必要,其余部分可以加上np。我必须说的是非常透彻的解释。唯一的问题是,如果使用numpy生成一个由零组成的空矩阵(比如说)
c
,将不会
np。append
抛出错误,而不是使用
c[i]=b[j]
。我已经为不同的数组大小编辑了一个补丁(只是交换了len(a)和len(b))。基本上-您现在所要做的就是确定坏数据的起始位置并将其删除,这样它就不会干扰比较。我提出了一个与您的解决方案非常类似的解决方案,只使用嵌套for循环,但它是一个quadra