【问题标题】:Better way to find existence of arrays in list of arrays在数组列表中查找数组存在的更好方法
【发布时间】:2012-01-01 06:22:07
【问题描述】:

我是 Python 的新手,正在尝试不同的方法来优化和简化我的代码。

我有一个数组列表(必须是这种格式)最初是空的,我需要用数组更新它,确保不添加重复的条目。

现在我正在按照以下方式进行操作,这是我尝试过的唯一有效的方法:

if len(where(((array(self.pop_next)-(self.pop[self.top_indv_indx[i]]))==0).sum(1)==len((self.pop[self.top_indv_indx[i]])))[0])<=0):
     self.pop_next.append(self.pop[self.top_indv_indx[i]])

self.pop_next 是我的数组列表,self.pop[self.top_indv_indx[i]] 是要添加的数组。

我知道这个 Unpythonic 并且猜想有更好的简单方法来做同样的事情。 请帮忙

【问题讨论】:

  • 什么是where?你在使用numpy 数组吗?如果你能把代码分成几行也很好
  • 是的,我正在使用 numpy 数组。现在我正在隐式尝试使用 where 关键字匹配数组。
  • 如果您尝试拥有一个包含不同对象的容器,也许您应该使用set 和您自己的__cmp__ 操作?你的项目是做什么的?
  • 我的项目与外部模拟器接口,因此我需要我的数据采用数组形式。我尝试过设置,但不知何故它不能直接工作,除非随后进行展平(这给了我一组数字而不是我需要的向量)

标签: python optimization numpy arraylist unique


【解决方案1】:

您可能想尝试使用numpy.all(array1 == array2) 作为单个数组比较的条件。

编辑中的扩展:

要遍历列表,您可以使用以下内容:

if all((numpy.all(array_to_add != a) for a in array_list)):
    array_list.append(array_to_add)

这会将array_to_addarray_list 的所有元素按值进行比较。请注意,这里的all__builtin__.all,与numpy.all 形成对比。如果您之前做过from numpy import *,这将不起作用。请改用import numpy,并按照上面的示例按全名调用函数。

如果可以按对象进行比较(即两个数组只有在内存中的对象完全相同时才相同),请使用以下更简单的变体:

if array_to_add is not in array_list:
    array_list.append(array_to_add)

【讨论】:

  • 但是我需要检查数组列表中是否存在一个数组,我猜你的代码只是帮助我比较 2 个数组。
  • “数组列表中存在数组”是否意味着存在完全相同的数组对象,或者只是存在恰好具有相同长度和值的任何数组?第一个很容易查,看list.index方法,或者直接object in list
  • 你的意思是尝试除索引检查之外的循环,但与我当前的代码相比,它不会降低我的代码效率吗?
【解决方案2】:

编辑:我从您的评论中看到您正在使用 numpy 数组。我从来没有使用过 numpy,所以我不知道它们是如何处理集合的。

一种选择是使用setSets are like lists 但它们是无序的,并且只允许每个项目添加一次:

>>> s = set()
>>> s.add(1)
>>> s.add(2)
>>> s.add(2)
>>> s.add(2)
>>> s
set([1, 2])

但是,如果您尝试将 list 添加到集合中,则会遇到问题:

>>> s.add(['my','list'])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

要添加到 set 的项目 must be hashablelist 不能是可散列的,因为它不能具有不变的散列值,因为它可以随时通过添加或删除值来修改。

如果您不需要要检查的列表是可变的,您可以将它们转换为固定的、可散列且易于设置的元组:

>>> mylist = ['my','list']
>>> s = set()
>>> s.add(tuple(mylist))
>>> s.add(tuple(mylist))
>>> s
set([('my', 'list')])

【讨论】:

  • 谢谢 Dave。我知道这很简单,但它也需要我将元组集转换回数组列表形式,因为我需要这个形式在并行评估器上运行它。跨度>
  • 根据您拥有的数组数量和它们的长度,使用set 的性能优势可能超过将数组转换为元组/从元组转换的成本。您可能需要使用timeit 和/或time 模块运行一些计时器测试。 timeit; time
猜你喜欢
  • 2019-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-06
  • 2013-03-23
  • 1970-01-01
  • 2013-12-31
相关资源
最近更新 更多