如何高效地将Numpy数组转换为集合?

25

我使用了:

df['ids'] = df['ids'].values.astype(set)

列表转换为集合,但输出结果是一个列表而不是一个集合:

>>> x = np.array([[1, 2, 2.5],[12,35,12]])

>>> x.astype(set)
array([[1.0, 2.0, 2.5],
       [12.0, 35.0, 12.0]], dtype=object)

有没有一种高效的方法可以在 Numpy 中将列表转换为集合?

编辑 1:
我的输入数据如下所示:
我有 3,000 条记录。每个记录都有 30,000 个 ID:[[1,...,12,13,...,30000],[1,..,43,45,...,30000],...,[…]]


1
@AlirezaHos,我觉得使用任何方法处理 x = np.array([[1, 2, 2.5],[12,35,12]]) 都不应该花费19秒钟的时间。你能详细说明一下吗? - Andras Deak -- Слава Україні
astype(set)并不是你想象中的那样。numpy没有set数据类型,所以它只会返回一个object数组。 - hpaulj
3个回答

29

首先将您的多维数组扁平化为一维数组,然后在其上应用set():

set(x.flatten())

编辑:看起来你只想要一个集合数组,而不是整个数组的集合,那么你可以使用value = [set(v) for v in x]获得一个集合列表。


2
@AlirezaHos 你有没有理由相信这个解决方案不是高效的?19秒内处理了多少数据?10个元素?100个?10^10个?还有为什么在原始问题中 没有包括完整的问题 的任何理由? - Andras Deak -- Слава Україні
1
@AlirezaHos 有没有特定的方法将所有数据转换为集合?将其存储为numpy数组应该非常高效。 - Divakar
1
@Divakar 特别是将其转换为集合应该涉及遍历每个元素并检查多重性和排序。难怪它很慢 :) - Andras Deak -- Слава Україні
1
@AlirezaHos 一个问题引发了10条评论,通常意味着原始帖子中缺少信息。请在以后的帖子中注意这一点。 - P. Camilleri
1
set(x.ravel()) 应该更有效率,因为它不会复制数组。(实际上,set(x.flat) 更好。) - endolith
显示剩余7条评论

14

您的问题当前的状态(可能随时更改):如何高效地从一个大数组的大数组中删除重复元素?

import numpy as np

rng = np.random.default_rng()
arr = rng.random((3000, 30000))
out1 = list(map(np.unique, arr))
#or
out2 = [np.unique(subarr) for subarr in arr]

在IPython shell中的运行时:

>>> %timeit list(map(np.unique, arr))
5.39 s ± 37.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

>>> %timeit [np.unique(subarr) for subarr in arr]
5.42 s ± 58.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

更新:正如@hpaulj在他的评论中指出的那样,我的虚拟示例存在偏见,因为浮点随机数几乎肯定是唯一的。所以这里有一个更真实的整数示例:

>>> arr = rng.integers(low=1, high=15000, size=(3000, 30000))

>>> %timeit list(map(np.unique, arr))
4.98 s ± 83.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

>>> %timeit [np.unique(subarr) for subarr in arr]
4.95 s ± 51.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

在这种情况下,输出列表的元素长度各不相同,因为存在需要移除的实际重复项。

问题不应该表述为“删除唯一元素”,而应该表述为“保留唯一元素”或“删除重复元素”,对吗? - Dimitri Lesnoff

1

@fabrik,那些是3年前的SO链接。按照您的逻辑,我们不能标记帖子为重复,而不重复旧答案。 - hpaulj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接