【问题标题】:How to filter two numpy arrays?如何过滤两个numpy数组?
【发布时间】:2021-11-06 19:27:58
【问题描述】:

编辑:我固定了 y 以使 x,y 具有相同的长度

我对编程不太了解,但我有大量数据要分析,而且必须用 Python 完成。 假设我有两个数组:

import numpy as np
x=np.array([1,2,3,4,5,6,7,8,9,10])
y=np.array([25,18,16,19,30,5,9,20,80,45])

并说我想选择 y 中大于 17 的值,并只保留 x 中与 y 中的左值具有相同索引的值。例如,我想删除 y (25) 的第一个值,并相应地删除 x (1) 中的匹配值。 我试过这个:

filter=np.where(y>17, 0, y)

但我不知道如何相应地过滤 x 值(实际数据是更长的数组,因此“手动”基本上是不可能的)

解决方案:使用@mozway 提示,现在 x,y 具有相同的长度,所需的代码是:

 import numpy as np
 x=np.array([1,2,3,4,5,6,7,8,9,10])
 y=np.array([25,18,16,19,30,5,9,20,80,45])
 x_filtered=x[y>17]

【问题讨论】:

    标签: python arrays numpy data-analysis


    【解决方案1】:

    由于您的问题并不完全清楚,并且您没有提供预期的输出,因此有两种可能性:

    过滤

    独特的数组可以被一个布尔数组(可迭代的)切片。

    如果两个数组的长度相同,您可以这样做:

    x[y>17]
    

    这里,xy 长,所以我们首先需要使其长度相同:

    import numpy as np
    x=np.array([1,2,3,4,5,6,7,8,9,10])
    y=np.array([25,18,16,19,30,5,9,20])
    
    x[:len(y)][y>17]
    

    输出:array([1, 2, 4, 5, 8])

    替换

    要根据条件在xy 之间进行选择,请使用where

    np.where(y>17, x[:len(y)], y)
    

    输出:

    array([ 1,  2, 16,  4,  5,  5,  9,  8])
    

    【讨论】:

    • 谢谢!我改变了y的长度。您提出的第一个选项更接近我的需要。
    【解决方案2】:

    作为一个在 Numpy 方面经验很少的人,我在看到@mozway 的过滤优秀答案之前写了这个答案。我的答案适用于比 Numpy 的数组更通用的容器,尽管它使用了更多的概念。我将尝试足够详细地解释每个概念,以使答案有意义。

    TL;DR:

    请务必阅读其余答案,它将帮助您了解发生了什么。

    import numpy as np
    x = np.array([1,2,3,4,5,6,7,8,9,10])
    y = np.array([25,18,16,19,30,5,9,20])
    
    filtered_x_list = []
    filtered_y_list = []
    
    for i in range(min(len(x), len(y))):
        if y[i] > 17:
            filtered_y_list.append(y[i])
            filtered_x_list.append(x[i])
    
    filtered_x = np.array(filtered_x_list)
    filtered_y = np.array(filtered_y_list)
    
    # These lines are just for us to see what happened
    print(filtered_x) # prints [1 2 4 5 8]
    print(filtered_y) # prints [25 18 19 30 20]
    

    必备知识

    Python 容器(列表、数组和其他我不会涉及的东西)

    让我们看一下这一行:

    x = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
    

    Python 在做什么?

    它做的第一件事是创建一个列表:

    [1, 2, 3] # and so on
    

    Python 中的列表有一些在这个解决方案中对我们有用的特性:

    访问元素:

    x_list = [ 1, 2, 3 ]
    print(x_list[0]) # prints 1
    print(x_list[1]) # prints 2, and so on
    

    在末尾添加元素:

    x_list = [ 1, 2, 3 ]
    x_list.append(4)
    print(x_list) # prints [1, 2, 3, 4]
    

    迭代:

    x_list = [ 1, 2, 3 ]
    for x in x_list:
        print(x)
    
    # prints:
    # 1
    # 2
    # 3
    

    Numpy 数组略有不同:我们仍然可以在其中访问迭代元素,但是一旦它们被创建,我们就不能修改它们——它们没有.append,还有其他一些可以用列表做的修改(比如改变一个值,或者删除一个值)我们不能用 numpy 数组做。

    所以filtered_x_listfiltered_y_list 是我们正在创建的空列表,但我们将通过在末尾添加我们关心的值来修改它们。

    Python 正在做的第二件事是创建一个 numpy 数组,使用列表来定义其内容。数组构造函数可以接受一个表示为[...] 的列表,或者一个由x_list = [...] 定义的列表,我们稍后会用到。

    关于迭代的更多信息

    在您的问题中,对于每个 x 元素,都有一个对应的 y 元素。我们想为每个y 元素测试一些东西,然后也对相应的x 元素进行操作。

    由于我们可以使用索引访问两个数组中的相同元素 - 例如,x[0] - 我们可以遍历所有需要访问的索引,而不是遍历一个列表或另一个列表列表。

    首先,我们需要弄清楚我们需要多少个索引,这只是列表的长度。 len(x) 让我们这样做 - 在这种情况下,它返回 10。

    如果xy 的长度不同怎么办?在这种情况下,我选择了两者中最小的一个——首先,执行len(x)len(y),然后将它们传递给min() function,这就是上面代码中min(len(x), len(y)) 的含义。

    最后,我们实际上要遍历索引,从 0 开始到 len(x) - 1len(y) - 1 结束,以最小者为准。 range sequence 让我们可以做到这一点:

    for i in range(10):
        print(i)
        
    # prints:
    # 0
    # 1
    # 2
    # 3
    # 4
    # 5
    # 6
    # 7
    # 8
    # 9
    

    所以range(min(len(x), len(y))),最后,让我们迭代的索引,最后,这行是有意义的:

    for i in range(min(len(x), len(y))):
    

    在这个 for 循环中,i 现在为我们提供了一个索引,我们可以将其用于xy

    现在,我们可以在 for 循环中进行比较:

    
    for i in range(min(len(x), len(y))):
        if y[i] > 17:
            filtered_y_list.append(y[i])
    

    然后,包括xs 对应的ys 是一个简单的情况,只需将相同的x 值附加到x 列表:

    for i in range(min(len(x), len(y))):
        if y[i] > 17:
            filtered_y_list.append(y[i])
            filtered_x_list.append(x[i])
    

    过滤后的列表现在包含您要查找的数字。最后两行,在 for 循环之外,只是从结果中创建 numpy 数组:

    
    filtered_x = np.array(filtered_x_list)
    filtered_y = np.array(filtered_y_list)
    

    如果某些 numpy 函数需要数组,您可能想要这样做。

    在我看来,虽然有更好的方法来做到这一点(我可能会编写自定义迭代器,在不创建新列表的情况下产生预期结果),但它们需要对编程有更深入的了解,所以我选择了更简单的方法.

    【讨论】:

      猜你喜欢
      • 2013-11-19
      • 2014-01-01
      • 2019-01-31
      • 2020-02-13
      • 2012-03-06
      • 2018-06-01
      • 1970-01-01
      相关资源
      最近更新 更多