在两个数组中查找唯一元素索引的 Pythonic 方法

2023-12-19

我有两个类似于这些的已排序的 numpy 数组:

x = np.array([1, 2, 8, 11, 15])
y = np.array([1, 8, 15, 17, 20, 21])

元素在同一个数组中永远不会重复。我想找出一个办法蟒蛇找出包含数组中存在相同元素的位置的索引列表。

例如,1存在于x and y在索引处0。元素2 in x不存在于y,所以我不关心该项目。然而,8确实存在于两个数组中 - 在索引中2 in x但索引1 in y。相似地,15两者都存在,在索引中4 in x,但索引2 in y。所以我的函数的结果将是一个列表,在这种情况下返回[[0, 0], [2, 1], [4, 2]].

到目前为止我正在做的是:

def get_indexes(x, y):
    indexes = []
    for i in range(len(x)):
        # Find index where item x[i] is in y:
        j = np.where(x[i] == y)[0]

        # If it exists, save it:
        if len(j) != 0:
            indexes.append([i, j[0]])

    return indexes

但问题是数组x and y are very大(数百万个项目),因此需要相当长的时间。有没有更好的pythonic这样做的方法?


没有 Python 循环

Code

def get_indexes_darrylg(x, y):
    ' darrylg answer '
    # Use intersect to find common elements between two arrays
    overlap = np.intersect1d(x, y)
    
    # Indexes of common elements in each array
    loc1 = np.searchsorted(x, overlap)
    loc2 = np.searchsorted(y, overlap)
    
    # Result is the zip two 1d numpy arrays into 2d array
    return np.dstack((loc1, loc2))[0]

Usage

x = np.array([1, 2, 8, 11, 15])
y = np.array([1, 8, 15, 17, 20, 21])
result = get_indexes_darrylg(x, y)

# result[0]: array([[0, 0],
                    [2, 1],
                    [4, 2]], dtype=int64)

发布时间解决方案

结果表明 darrlg 代码的运行时间最快。

代码调整

  • 每个发布的解决方案都是一个函数。
  • 稍微修改一下,使每个解决方案输出一个 numpy 数组。
  • 以海报命名的曲线

Code

import numpy as np
import perfplot

def create_arr(n):
    ' Creates pair of 1d numpy arrays with half the elements equal '
    max_val = 100000     # One more than largest value in output arrays
    
    arr1 = np.random.randint(0, max_val, (n,))
    arr2 = arr1.copy()
    
    # Change half the elements in arr2
    all_indexes = np.arange(0, n, dtype=int)
    indexes = np.random.choice(all_indexes, size = n//2, replace = False) # locations to make changes
    
    
    np.put(arr2, indexes, np.random.randint(0, max_val, (n//2, )))        # assign new random values at change locations
   
    arr1 = np.sort(arr1)
    arr2 = np.sort(arr2)
    
    return (arr1, arr2)

def get_indexes_lllrnr101(x,y):
    ' lllrnr101 answer '
    ans = []
    i=0
    j=0
    while (i<len(x) and j<len(y)):
        if x[i] == y[j]:
            ans.append([i,j])
            i += 1
            j += 1
        elif (x[i]<y[j]):
            i += 1
        else:
            j += 1
    return np.array(ans)

def get_indexes_joostblack(x, y):
    'joostblack'
    indexes = []
    for idx,val in enumerate(x):
        idy = np.searchsorted(y,val)
        try:
            if y[idy]==val:
                indexes.append([idx,idy])
        except IndexError:
            continue  # ignore index errors
            
    return np.array(indexes)

def get_indexes_mustafa(x, y):
    indices_in_x = np.flatnonzero(np.isin(x, y))                 # array([0, 2, 4])
    indices_in_y = np.flatnonzero(np.isin(y, x[indices_in_x]))   # array([0, 1, 2]
    
    return np.array(list(zip(indices_in_x, indices_in_y)))

def get_indexes_darrylg(x, y):
    ' darrylg answer '
    # Use intersect to find common elements between two arrays
    overlap = np.intersect1d(x, y)
    
    # Indexes of common elements in each array
    loc1 = np.searchsorted(x, overlap)
    loc2 = np.searchsorted(y, overlap)
    
    # Result is the zip two 1d numpy arrays into 2d array
    return np.dstack((loc1, loc2))[0]

def get_indexes_akopcz(x, y):
    ' akopcz answer '
    return np.array([
        [i, j]
        for i, nr in enumerate(x)
        for j in np.where(nr == y)[0]
    ])

perfplot.show(
    setup = create_arr,  # tuple of two 1D random arrays
    kernels=[
        lambda a: get_indexes_lllrnr101(*a),
        lambda a: get_indexes_joostblack(*a),
        lambda a: get_indexes_mustafa(*a),
        lambda a: get_indexes_darrylg(*a),
        lambda a: get_indexes_akopcz(*a),
    ],
    labels=["lllrnr101", "joostblack", "mustafa", "darrylg", "akopcz"],
    n_range=[2 ** k for k in range(5, 21)],
    xlabel="Array Length",
    # More optional arguments with their default values:
    # logx="auto",  # set to True or False to force scaling
    # logy="auto",
    equality_check=None, #np.allclose,  # set to None to disable "correctness" assertion
    # show_progress=True,
    # target_time_per_measurement=1.0,
    # time_unit="s",  # set to one of ("auto", "s", "ms", "us", or "ns") to force plot units
    # relative_to=1,  # plot the timings relative to one of the measurements
    # flops=lambda n: 3*n,  # FLOPS plots
)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在两个数组中查找唯一元素索引的 Pythonic 方法 的相关文章

随机推荐

  • React组件回调实现方法有什么区别

    import React from react import ChildComponent from ChildComponent class SampleComponent extends React Component sampleCa
  • 如何在 cefsharp WPF 项目中加载扩展?

    我正在尝试在 WPF 项目中的 cefsharp 嵌入式浏览器中加载扩展 但这样做时应用程序会冻结 这是我一直在加载一个非常简单的扩展的代码 var setting new CefSettings setting RegisterExten
  • 类型不可序列化,因为它不是公共的?

    我有一个无法正确序列化的公共类 尝试时 会引发以下异常 数据协定类型 MyProject MyClass 不可序列化 因为它不是公共的 公开该类型将修复此错误 或者 您可以将其设置为内部 并使用程序集上的 InternalsVisibleT
  • 控制java调度算法

    今天我和一位有趣的受访者交谈 他坚持认为提高 Java 应用程序性能的最佳方法是重写线程调度算法 鉴于我们依赖 JVM 线程调度算法 我有理由确信这是不可能的 但我想知道是否有任何技术可以用来影响调度算法 或者如果有一个令人信服的理由这样做
  • 在此 P/Invoke 用例中正确使用 SafeHandles

    在 C 中使用本机 Dll 使用不透明句柄和内部引用计数 我有以下 P Invoke 签名 全部用 DllImport 属性装饰 DllImport somedll dll public extern IntPtr getHandleOfA
  • 等值线世界地图

    我读了很多帖子和文章 但不断出现错误 我正在尝试制作一个等值线 使用我从全球恐怖主义数据库获得的数据绘制的世界地图 我想根据击杀次数或仅根据该国家 地区的攻击次数对国家进行着色 我现在不在乎 由于拥有数据的国家太多 因此绘制任何图表来显示这
  • 通过 VIM 选择 Python 函数的最快方法是什么?

    没有任何插件可以吗 或者编辑 python 文件的最佳插件是什么 try vis直观地选择和o跳跃边缘
  • 来自工作人员的错误消息: generic::aborted: SDKharness sdk-0-1 已断开连接

    我的一项 Dataflow 作业遇到一些问题 我有时会收到此错误消息 似乎在这个错误之后 作业一直运行良好 但是 今天晚上它实际上卡住了 或者它开始缓慢地处理元素 您还可以从屏幕截图中看到 工作人员开始表现得非常奇怪 如下面屏幕截图中的 C
  • 您可以在 iPhone/iPad 上的视图之间进行转换的完整列表 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • gcc execstack 标志到底允许什么情况以及它如何强制执行它?

    我这里有一些示例代码 我用它们来理解初学者 CTF 的一些 C 行为 example c include
  • 两个纬度和经度之间的行进距离

    我正在计算并给出公路旅行的两组纬度和经度之间的距离 我查看了 Google 的方向和距离矩阵 API 并且还做了很多关于SO的其他问题 但我无法找出最好的方法 您需要每次计算到大约 20 25 个位置的距离 我们正在构建一款旅行应用程序 该
  • 显示延迟的网络摄像头/摄像头流 - webrtc

    我做了一个简单的设置 获取网络摄像头 手机摄像头流并将其传递 在 html 2d 画布上绘图 但我一直无法弄清楚如何以几秒钟的延迟显示流 有点像延迟镜 我尝试玩ctx globalAlpha 0 005 但这给了我重影效果而不是 延迟 流
  • 在android中读取EditText的文本

    我正在编写一个简单的 Android 应用程序 它有一个编辑文本和一个按钮 单击按钮应显示一个警报对话框 其中包含在编辑文本中输入的文本 为此 我有以下代码 String txt Called when the activity is fi
  • EMGU QueryFrame 通过 RTSP 返回“条纹”图像

    我有一个高清网络摄像机 我试图通过 rtsp 抓取帧并使用以下代码 in Form Load Application Idle getNextFrame 和事件处理程序 private void getNextFrame object se
  • 如何删除google colab本地上传的文件?

    我正在尝试使用以下代码删除我在 Google colab 上上传的文件 from google colab import files uploaded files upload 现在如何删除该文件 例如 如果文件的名称是 sample jp
  • WorksheetFunction.Transpose 更改数据类型

    我正在使用WorksheetFunction Transpose在 VBA 中将混合日期 字符串的一维数组转换为二维数组以写入工作表 我的 Windows 区域设置设置为DMY 写回的日期有月 日切换 这个论坛里已经提到过Dates正在转换
  • 如何实现一个非常简单的文件系统?

    我想知道操作系统如何读取 写入硬盘 我想作为练习来实现一个简单的文件系统 没有可以读写文件的目录 我从哪说起呢 C C 可以解决这个问题还是我必须采用更底层的方法 一个人处理的事情是否太多了 看看保险丝 http fuse sourcefo
  • Objective-c 多播委托

    我在 xcode 中创建新的选项卡式视图项目 在 appdelegate 中我创建了一个协议 h file protocol myProtocol
  • 在 Java 中从 json 文件中删除 json 对象

    我有一个在线下载的 json 文件 price 1 empty 0 0 0 0 0 lowValue 0 highValue 0 我想删除其中的所有内容 空的 to 我花了几个小时研究正则表达式的东西 但我似乎不知道如何让它做我想做的事情
  • 在两个数组中查找唯一元素索引的 Pythonic 方法

    我有两个类似于这些的已排序的 numpy 数组 x np array 1 2 8 11 15 y np array 1 8 15 17 20 21 元素在同一个数组中永远不会重复 我想找出一个办法蟒蛇找出包含数组中存在相同元素的位置的索引列