【问题标题】:How to remove duplicates in a numpy array and keep its sorting如何删除 numpy 数组中的重复项并保持其排序
【发布时间】:2021-04-17 13:21:56
【问题描述】:

我有一个 numpy 数组列表,想要删除重复项并保持排序数据的顺序。这是我的重复数组:

dup_arr=[np.array([[0., 10., 10.],\
                   [0., 2., 30.],\
                   [0., 3., 5.],\
                   [0., 3., 5.],\
                   [0., 3., 40.]]),\
         np.array([[0., -1., -4.],\
                   [0., -2., -3.],\
                   [0., -3., -5.],\
                   [0., -3., -6.],\
                   [0., -3., -6.]])]

我尝试使用以下代码:

clean_arr=[]
for i in dup_arr:
    new_array = [tuple(row) for row in i]
    uniques = np.unique(new_array, axis=0)
    clean_arr.append(uniques)

但是这种方法的问题是它改变了我的数据的排序,我不想再次对它们进行排序,因为这对我的真实数据来说是一项艰巨的任务。我想得到以下结果:

clean_arr=[np.array([[0., 10., 10.],\
                     [0., 2., 30.],\
                     [0., 3., 5.],\
                     [0., 3., 40.]]),\
           np.array([[0., -1., -4.],\
                     [0., -2., -3.],\
                     [0., -3., -5.],\
                     [0., -3., -6.]])]

但是代码会打乱它。我也尝试了愚蠢的 for 循环,但它也没有成功,因为我无法迭代直到我的数据结束并在到达我的列表的每个数组的末尾之前停止第二个 for 循环。

clean_arr=[]
for arrays in dup_arr:
    for rows in range (len(arrays)-1):
        if np.all(arrays [rows]== arrays [rows+1]):
            continue
        else:
            dat= arrays [rows]
            clean_arr.append(dat)

在此先感谢您的帮助和贡献。

【问题讨论】:

    标签: python arrays numpy duplicates


    【解决方案1】:

    您可以简单地将np.uniqueaxis=0 一起使用。如果你想保持原始序列的顺序,试试这个 -

    [i[np.sort(np.unique(i, axis=0, return_index=True)[1])] for i in dup_arr]
    
    [array([[ 0., 10., 10.],
            [ 0.,  2., 30.],
            [ 0.,  3.,  5.],
            [ 0.,  3., 40.]]),
     array([[ 0., -1., -4.],
            [ 0., -2., -3.],
            [ 0., -3., -5.],
            [ 0., -3., -6.]])]
    
    1. np.unique(i, axis=0, return_index=True)[1] 返回唯一元素的索引。
    2. np.sort() 将这些索引排序回数组中的原始序列。
    3. [f(i) for i in dup_arr] 对 dup_arr 中的每个元素应用上述 2 个步骤。

    注意:您将无法完全矢量化此操作(例如 np.stack 在此操作上,因为它可能会从每个矩阵中删除变量重复项。这将导致 numpy 数组在轴上具有不相等的形状。


    将步骤分解为函数-

    def f(a):
        indexes = np.unique(a, axis=0, return_index=True)[1]
        return a[np.sort(indexes)]
    
    [f(i) for i in dup_arr]
    

    【讨论】:

    • 亲爱的@Akshay Sehgal,感谢您抽出宝贵时间。我很欣赏你的解决方案。但是,问题是你的解决方案改变了我的初始数组的排序,我不想改变它。我只想删除重复的行,其他行应该保持在它们的相对位置。我的意思是它们不应该向上或向下移动。
    • 更新了我的答案,请检查并让我知道它是否解决了。
    • 在删除第二个列表理解后将其更改为单行。这里只需要 1 个。
    • 亲爱的@Akshay Sehgal,再次感谢您提供的帮助。如果您还保留 functoin 方法,也许您的帖子会提供更多信息。我想你在上次编辑中删除了它。
    • 确定添加以获取更多详细信息
    【解决方案2】:

    以我的拙见,每次你想在 Python 中从数组或列表中删除重复项时,都应该考虑使用集合。

    另外,尽量避免使用多个嵌套循环,因为错误很容易发生并且很难找到。我建议你试试下面的代码:

    removed_duplicates=[]
        
    for subarr in dup_arr:
        removed_duplicates.append(np.array([list(item) for item in set(tuple(row) for row in subarr)]))
    

    基本上发生的事情是将数组转换为元组,然后转换为删除所有重复项的集合,然后转换为列表。由于您的原始数据有一个 np.arrays 数组,因此您将列表转换回 np.array,然后再将其附加到新数组。

    这行得通吗?

    【讨论】:

    • 亲爱的@Erik Hallin,感谢您抽出宝贵时间。我很欣赏你的解决方案。问题是我的排序数组被你的解决方案改变了,我想保持我的初始数组的排序。我只想删除重复项,不要碰排序。
    猜你喜欢
    • 2019-02-18
    • 2014-11-05
    • 2022-01-03
    • 2018-01-26
    • 2011-03-05
    • 1970-01-01
    • 2016-10-01
    • 2013-09-26
    • 1970-01-01
    相关资源
    最近更新 更多