gpt4 book ai didi

python - 删除数组中重复的列,保持顺序

转载 作者:太空宇宙 更新时间:2023-11-03 16:06:20 24 4
gpt4 key购买 nike

是否有一种相对简单的方法来删除(numpy)数组的列并保持列的顺序?

作为一个例子,考虑这个数组:

a = np.array([[2, 1, 1, 3],
[2, 1, 1, 3]])

我希望删除第三列,以便:

a = np.array([[2, 1, 3],
[2, 1, 3]])

最佳答案

方法#1这是一种使用 broadcasting 的方法-

a[:,~np.triu((a[:,None,:] == a[...,None]).all(0),1).any(0)]

示例运行 -

In [115]: a
Out[115]:
array([[2, 1, 3, 5, 1, 3, 7],
[6, 5, 4, 6, 5, 4, 8]])

In [116]: a[:,~np.triu((a[:,None,:] == a[...,None]).all(0),1).any(0)]
Out[116]:
array([[2, 1, 3, 5, 7],
[6, 5, 4, 6, 8]])

说明

1) 输入数组 -

In [156]: a
Out[156]:
array([[2, 1, 3, 5, 1, 3, 7],
[6, 5, 4, 6, 5, 4, 8]])

2) 使用广播执行元素相等比较,保持第一个轴对齐,这将对应于原始 2D 数组中的列轴 -

In [157]: a[:,None,:] == a[...,None]
Out[157]:
array([[[ True, False, False, False, False, False, False],
[False, True, False, False, True, False, False],
[False, False, True, False, False, True, False],
[False, False, False, True, False, False, False],
[False, True, False, False, True, False, False],
[False, False, True, False, False, True, False],
[False, False, False, False, False, False, True]],

[[ True, False, False, True, False, False, False],
[False, True, False, False, True, False, False],
[False, False, True, False, False, True, False],
[ True, False, False, True, False, False, False],
[False, True, False, False, True, False, False],
[False, False, True, False, False, True, False],
[False, False, False, False, False, False, True]]], dtype=bool)

3) 由于我们正在寻找重复的列,因此让我们沿着第一个轴查找所有匹配项 -

In [158]: (a[:,None,:] == a[...,None]).all(0)
Out[158]:
array([[ True, False, False, False, False, False, False],
[False, True, False, False, True, False, False],
[False, False, True, False, False, True, False],
[False, False, False, True, False, False, False],
[False, True, False, False, True, False, False],
[False, False, True, False, False, True, False],
[False, False, False, False, False, False, True]], dtype=bool)

4) 我们希望仅保留第一次出现,因此我们可以使用上三角矩阵将所有对角线和下三角元素设置为 False -

In [163]: np.triu((a[:,None,:] == a[...,None]).all(0),1)
Out[163]:
array([[False, False, False, False, False, False, False],
[False, False, False, False, True, False, False],
[False, False, False, False, False, True, False],
[False, False, False, False, False, False, False],
[False, False, False, False, False, False, False],
[False, False, False, False, False, False, False],
[False, False, False, False, False, False, False]], dtype=bool)

5) 接下来,我们沿着第一个轴查找任何表示重复项的匹配项 -

In [164]: (np.triu((a[:,None,:] == a[...,None]).all(0),1)).any(0)
Out[164]: array([False, False, False, False, True, True, False], dtype=bool)

6)我们希望删除这些重复项,因此反转掩码 -

In [165]: ~(np.triu((a[:,None,:] == a[...,None]).all(0),1)).any(0)
Out[165]: array([ True, True, True, True, False, False, True], dtype=bool)

7) 最后,我们使用最终输出的掩码对输入数组的列进行索引 -

In [166]: a[:,~(np.triu((a[:,None,:] == a[...,None]).all(0),1)).any(0)]
Out[166]:
array([[2, 1, 3, 5, 7],
[6, 5, 4, 6, 8]])
<小时/>

方法 #2 重点关注内存效率,甚至可能更快,这是一种将每一列视为索引元组的方法 -

lidx = np.ravel_multi_index(a,a.max(1)+1)
out = a[:,np.sort(np.unique(lidx,return_index=1)[1])]

说明

1) 输入数组 -

In [203]: a
Out[203]:
array([[2, 1, 3, 5, 1, 3, 7],
[6, 5, 4, 6, 5, 4, 8]])

2) 计算每列的线性索引当量 -

In [207]: lidx = np.ravel_multi_index(a,a.max(1)+1)

In [208]: lidx
Out[208]: array([24, 14, 31, 51, 14, 31, 71])

3)获取每个唯一线性索引的第一次出现

In [209]: np.unique(lidx,return_index=1)[1]
Out[209]: array([1, 0, 2, 3, 6])

4) 对它们进行排序并索引到输入数组的列中以用于最终的 o/p -

In [210]: np.sort(np.unique(lidx,return_index=1)[1])
Out[210]: array([0, 1, 2, 3, 6])

In [211]: a[:,np.sort(np.unique(lidx,return_index=1)[1])]
Out[211]:
array([[2, 1, 3, 5, 7],
[6, 5, 4, 6, 8]])

有关转换为索引元组的注意事项的详细信息,请参阅 this post .

关于python - 删除数组中重复的列,保持顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39743315/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com