【问题标题】:Searching in numpy array在numpy数组中搜索
【发布时间】:2021-06-03 14:27:32
【问题描述】:

我有一个 2D numpy 数组,比如 A 相对于第 0 列排序。例如

Col.0 Col.1 Col.2
10 2.45 3.25
11 2.95 4
12 3.45 4.25
15 3.95 5
18 4.45 5.25
21 4.95 6
23 5.45 6.25
27 5.95 7
29 6.45 7.25
32 6.95 8
35 7.45 8.25

每行中的条目是唯一的,即第 0 列是 xy 平面中坐标的标识号,第 1 列和第 2 列是这些点的 x 和 y 坐标。 我有另一个数组 B(行可以包含重复数据)。第 0 列和第 1 列存储 x 和 y 坐标。

Col.0 Col.1
2.45 3.25
4.45 5.25
6.45 7.25
2.45 3.25

我的目标是在不使用 for 循环的情况下找到数组 A 中与数组 B 中的数据对应的行索引号。所以,在这种情况下,我的输出应该是[0,4,8,0]。 现在,我知道使用 numpy searchsorted 查找多个数据可以一次性完成。但是,它可以用来与 A 的单列而不是多列进行比较。有没有办法做到这一点?

【问题讨论】:

  • searchsorted 无济于事,因为该数组未按您实际搜索的列排序。
  • 请避免为数据框发布表格。发布实际数据(或者更好的数据框代码)将帮助我们运行您的示例数据。

标签: python arrays pandas numpy


【解决方案1】:

您可以在 pandas 中使用合并:

df2.merge(df1.reset_index(),how='left',left_on=['Col.0','Col.1'],right_on=['Col.1','Col.2'])['index']

输出:

0    0
1    4
2    8
3    0
Name: index, dtype: int64

如果你喜欢它作为数组:

df2.merge(df1.reset_index(),how='left',left_on=['Col.0','Col.1'],right_on=['Col.1','Col.2'])['index'].to_numpy()
#array([0, 4, 8, 0])

【讨论】:

    【解决方案2】:

    纯 numpy 解决方案:

    我的直觉是,我通过广播获取a[:,1:]b 之间的c 差异,因此c 的形状为(11, 4, 2)。匹配的行将全为零。然后我做c == False 来获得一个面具。我做c.all(2) 会产生一个形状为(11, 4) 的布尔数组,其中所有True 元素表示ab 之间的匹配。然后我只需使用np.nonzero 来获取所述元素的索引。

    import numpy as np
    
    a = np.array([
        [10, 2.45, 3.25],
        [11, 2.95, 4],
        [12, 3.45, 4.25],
        [15, 3.95, 5],
        [18, 4.45, 5.25],
        [21, 4.95, 6],
        [23, 5.45, 6.25],
        [27, 5.95, 7],
        [29, 6.45, 7.25],
        [32, 6.95, 8],
        [35, 7.45, 8.25],
    ])
    
    b = np.array([
        [2.45, 3.25],
        [4.45, 5.25],
        [6.45, 7.25],
        [2.45, 3.25],
    ])
    
    c = (a[:,np.newaxis,1:]-b) == False
    rows, cols = c.all(2).nonzero()
    print(rows[cols.argsort()])
    # [0 4 8 0]
    

    【讨论】:

    • 这真的很有帮助。我现在可以在一个非常大的数组中实现这个逻辑。
    • @SudiptaLalBasu 很高兴看到它对您有用!但是,我注意到当第一个或第二个元素相等时,我的代码匹配。如果你有所有连续点,它可能对你有用,因为它们不太可能得到完全相同的值,但它不是严格正确的,因为它可以匹配太多。为确保您需要两个元素匹配,请将:rows, cols = c.sum(2).nonzero() 更改为 rows, cols = c.all(2).nonzero(),我将编辑我的提交以反映这一点。给您带来的不便深表歉意!
    猜你喜欢
    • 2012-10-22
    • 1970-01-01
    • 2016-07-31
    • 2016-05-24
    • 1970-01-01
    • 1970-01-01
    • 2018-11-19
    • 1970-01-01
    • 2021-02-28
    相关资源
    最近更新 更多