首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从numPy数组列表中删除重复项

从numPy数组列表中删除重复项
EN

Stack Overflow用户
提问于 2015-01-03 02:12:27
回答 3查看 7.2K关注 0票数 7

我有一个普通的Python,它包含(多维) numPy数组,所有这些数组都是相同的形状,具有相同数量的值。列表中的一些数组是早期数组的副本。

我有一个问题,我想删除所有的重复,但事实上,数据类型是numPy数组使这有点复杂……

·我不能使用set(),因为numPy数组是不可接受的。

·我无法在插入过程中检查重复项,因为数组是由函数批量生成的,并使用.extend()添加到列表中。

·如果不使用numPy自己的函数之一,numPy数组就无法直接比较,所以我不能只使用“如果x在列表中”.

·列表的内容在进程结束时需要保持为numPy数组;我可以比较转换为嵌套列表的数组的副本,但我不能永久地将数组转换为直接的python列表。

关于我如何有效地删除这里的副本有什么建议吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-01-03 02:18:43

使用这里的解决方案:Most efficient property to hash for numpy array,我们可以看到,如果a是numpy数组,哈希对a.tostring()最有效。所以:

代码语言:javascript
运行
复制
import numpy as np
arraylist = [np.array([1,2,3,4]), np.array([1,2,3,4]), np.array([1,3,2,4])]
L = {array.tostring(): array for array in arraylist}
L.values() # [array([1, 3, 2, 4]), array([1, 2, 3, 4])]
票数 6
EN

Stack Overflow用户

发布于 2015-01-03 16:29:20

根据数据的结构,直接比较所有数组可能会更快,而不是找到散列数组的方法。算法是O(n^2),但是每个单独的比较都比创建数组的字符串或python列表要快得多。这取决于你要检查多少个数组。

例如:

代码语言:javascript
运行
复制
uniques = []
for arr in possible_duplicates:
    if not any(numpy.array_equal(arr, unique_arr) for unique_arr in uniques):
        uniques.append(arr)
票数 5
EN

Stack Overflow用户

发布于 2015-01-03 02:28:43

这里有一种使用tuple的方法

代码语言:javascript
运行
复制
>>> import numpy as np
>>> t = [np.asarray([1, 2, 3, 4]), 
         np.asarray([1, 2, 3, 4]), 
         np.asarray([1, 1, 3, 4])]

>>> map(np.asarray, set(map(tuple, t)))
[array([1, 1, 3, 4]), array([1, 2, 3, 4])]

如果您的数组是多维的,那么首先将它们夷为平地,然后使用相同的想法,并在最后对它们进行整形:

代码语言:javascript
运行
复制
def to_tuple(arr):
    return tuple(arr.reshape((arr.size,)))

def from_tuple(tup, original_shape):
    np.asarray(tup).reshape(original_shape)

示例:

代码语言:javascript
运行
复制
In [64]: t = np.asarray([[[1,2,3],[4,5,6]],
                         [[1,1,3],[4,5,6]],
                         [[1,2,3],[4,5,6]]])

In [65]: map(lambda x: from_tuple(x, t[0].shape), set(map(to_tuple, t)))
Out[65]: 
[array([[1, 2, 3],
        [4, 5, 6]]), 
 array([[1, 1, 3],
        [4, 5, 6]])]

另一种选择是从你的pandas.DataFrame中创建一个ndarrays (如果需要的话,可以将它们作为行来处理),并使用熊猫内置的方式来实现行的独特性。

代码语言:javascript
运行
复制
In [34]: t
Out[34]: [array([1, 2, 3, 4]), array([1, 2, 3, 4]), array([1, 1, 3, 4])]

In [35]: pandas.DataFrame(t).drop_duplicates().values
Out[35]: 
array([[1, 2, 3, 4],
       [1, 1, 3, 4]])

总的来说,我认为尝试使用tostring()作为准散列函数是个坏主意,因为比起我的方法,您需要更多的锅炉板代码来防止某些内容在某些dict中被分配“散列”键后发生变异的可能性。

如果考虑到数据的大小,重塑和转换到tuple的速度太慢,我的感觉是,这揭示了一个更根本的问题:应用程序的设计不是很好地满足需求(比如去欺骗),并且尝试将它们塞进内存中运行的Python进程可能不是正确的方法。在这一点上,我会停下来考虑一下,像Cassandra这样的东西,它可以很容易地在浮点(或其他)数据的大列(或多维数组)的基础上构建数据库索引,这是不是更明智的方法。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27751072

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档