- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
对于大数组(n>1e8),有没有比np.isin
更快的方法来检查是否有相同的元素?
我已经尝试了几种方法,如 pandas isin
、cython,但所有这些方法都比 np.isin
示例:(测试一维数组的每个元素是否也存在于第二个数组中)
num = int(1e8)
a = np.random.rand(int(num))
b = np.random.rand(int(num))
ref=time.time()
ainb = np.isin(a,b)
print(a[ainb])
print(time.time()-ref,'sec')
>>> [0.23591019 0.46102523]
>>> 65.45570135116577 sec
最佳答案
如果您需要插入(针对您的用例)但可能更快地替换 np.isin()
,您可以使用 Python set()
进行检查并加速 Numba 中的显式循环:
import numpy as np
import numba as nb
@nb.jit
def is_in_set_nb(a, b):
shape = a.shape
a = a.ravel()
n = len(a)
result = np.full(n, False)
set_b = set(b)
for i in range(n):
if a[i] in set_b:
result[i] = True
return result.reshape(shape)
请注意,有一些(廉价的)额外代码可以使其适用于 N-dim 数组,如果您只需要 1D,则可以忽略这些代码。
这甚至可以通过添加进一步的并行化来变得更快:
import numpy as np
import numba as nb
@nb.jit(parallel=True)
def is_in_set_pnb(a, b):
shape = a.shape
a = a.ravel()
n = len(a)
result = np.full(n, False)
set_b = set(b)
for i in nb.prange(n):
if a[i] in set_b:
result[i] = True
return result.reshape(shape)
这比 np.isin()
、set()
交集和没有 Numba 加速的 is_in_set()
解决方案要快得多:
def is_in_set(a, b):
set_b = set(b)
return np.array([x in set_b for x in a])
输入大小为一千万个元素:
n = 10 ** 7
k = n // 3
np.random.seed(0)
# note: I used `int`s because I wanted to be able to control the collisions
a = np.random.randint(0, k * n, n)
b = np.random.randint(0, k * n, n)
%timeit ainb = np.isin(a, b); a[ainb]
# 1 loop, best of 3: 3.94 s per loop
%timeit ainb = is_in_set_nb(a, b); a[ainb]
# 1 loop, best of 3: 814 ms per loop
%timeit ainb = is_in_set_pnb(a, b); a[ainb]
# 1 loop, best of 3: 740 ms per loop
%timeit ainb = is_in_set(a, b); a[ainb]
# 1 loop, best of 3: 7.69 s per loop
%timeit set(a).intersection(b) # not a drop-in replacement
# 1 loop, best of 3: 6.79 s per loop
%timeit set(a) & set(b) # not a drop-in replacement
# 1 loop, best of 3: 8.98 s per loop
并且有亿个元素(最后两种方法最终填满了所有内存,因此被省略):
n = 10 ** 8
k = n // 3
np.random.seed(0)
a = np.random.randint(0, k * n, n)
b = np.random.randint(0, k * n, n)
%timeit ainb = np.isin(a, b); a[ainb]
# 1 loop, best of 3: 1min 4s per loop
%timeit ainb = is_in_set_nb(a, b); a[ainb]
# 1 loop, best of 3: 13.1 s per loop
%timeit ainb = is_in_set_pnb(a, b); a[ainb]
# 1 loop, best of 3: 11.4 s per loop
%timeit ainb = is_in_set(a, b); a[ainb]
# 1 loop, best of 3: 2min 5s per loop
为较小的输入添加更多计时,但 a
和 b
的所有长度组合:
funcs = np.isin, is_in_set_nb, is_in_set_pnb
sep = ' '
print(f'({"n=len(a)":>9s},{"m=len(b)":>9s})', end=sep)
for func in funcs:
print(f'{func.__name__:15s}', end=sep)
print()
I, J = 7, 7
for i in range(I):
for j in range(J):
n = 10 ** i
m = 10 ** j
a = np.random.randint(0, m * n, n)
b = np.random.randint(0, m * n, m)
print(f'({n:9d},{m:9d})', end=sep)
for func in funcs:
result = %timeit -q -o func(a, b)
print(f'{result.best * 1e3:12.3f} ms', end=sep)
print()
( n=len(a), m=len(b)) isin is_in_set_nb is_in_set_pnb
( 1, 1) 0.011 ms 0.001 ms 0.047 ms
( 1, 10) 0.048 ms 0.001 ms 0.023 ms
( 1, 100) 0.050 ms 0.002 ms 0.027 ms
( 1, 1000) 0.102 ms 0.007 ms 0.041 ms
( 1, 10000) 0.766 ms 1.028 ms 1.122 ms
( 1, 100000) 9.717 ms 3.426 ms 3.356 ms
( 1, 1000000) 105.154 ms 43.642 ms 40.734 ms
( 10, 1) 0.010 ms 0.001 ms 0.023 ms
( 10, 10) 0.030 ms 0.001 ms 0.023 ms
( 10, 100) 0.053 ms 0.002 ms 0.027 ms
( 10, 1000) 0.100 ms 0.007 ms 0.055 ms
( 10, 10000) 0.961 ms 1.031 ms 1.154 ms
( 10, 100000) 9.772 ms 3.595 ms 3.761 ms
( 10, 1000000) 105.802 ms 54.260 ms 50.265 ms
( 100, 1) 0.010 ms 0.001 ms 0.024 ms
( 100, 10) 0.030 ms 0.002 ms 0.025 ms
( 100, 100) 0.054 ms 0.002 ms 0.026 ms
( 100, 1000) 0.105 ms 0.008 ms 0.045 ms
( 100, 10000) 0.751 ms 1.076 ms 1.158 ms
( 100, 100000) 9.824 ms 3.253 ms 3.329 ms
( 100, 1000000) 105.697 ms 57.993 ms 55.285 ms
( 1000, 1) 0.012 ms 0.005 ms 0.028 ms
( 1000, 10) 0.038 ms 0.006 ms 0.029 ms
( 1000, 100) 0.119 ms 0.007 ms 0.033 ms
( 1000, 1000) 0.180 ms 0.014 ms 0.063 ms
( 1000, 10000) 0.821 ms 1.074 ms 1.169 ms
( 1000, 100000) 9.920 ms 3.392 ms 3.532 ms
( 1000, 1000000) 104.666 ms 57.845 ms 54.603 ms
( 10000, 1) 0.020 ms 0.041 ms 0.092 ms
( 10000, 10) 0.089 ms 0.088 ms 0.158 ms
( 10000, 100) 0.967 ms 0.112 ms 0.182 ms
( 10000, 1000) 1.017 ms 0.161 ms 0.249 ms
( 10000, 10000) 1.633 ms 1.137 ms 1.283 ms
( 10000, 100000) 10.754 ms 3.027 ms 3.302 ms
( 10000, 1000000) 101.926 ms 48.062 ms 49.117 ms
( 100000, 1) 0.071 ms 0.409 ms 0.455 ms
( 100000, 10) 0.575 ms 0.916 ms 0.803 ms
( 100000, 100) 16.304 ms 1.201 ms 0.940 ms
( 100000, 1000) 15.185 ms 1.566 ms 1.181 ms
( 100000, 10000) 15.914 ms 1.454 ms 1.252 ms
( 100000, 100000) 23.719 ms 4.820 ms 4.313 ms
( 100000, 1000000) 119.668 ms 56.863 ms 54.570 ms
( 1000000, 1) 0.774 ms 4.347 ms 3.407 ms
( 1000000, 10) 6.207 ms 8.793 ms 5.957 ms
( 1000000, 100) 178.498 ms 13.104 ms 8.544 ms
( 1000000, 1000) 169.022 ms 16.198 ms 10.283 ms
( 1000000, 10000) 177.986 ms 13.243 ms 8.973 ms
( 1000000, 100000) 177.989 ms 19.856 ms 13.898 ms
( 1000000, 1000000) 283.207 ms 97.118 ms 84.332 ms
这表明 Numba 和并行化对于较大的输入非常有利,而对于较小的输入则效率稍低。然而,在上述大多数测试中,它们仍然优于np.isin()
。
关于python - 对于大型数组,有没有比 np.isin 更快的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62007409/
我正在使用 Pandas 和 Python 导入一个 CSV,并对导入的数据框中的数据进行操作,以便创建一个新列。 新列中的每一行都是基于 A 列和 B 列的每个对应行中的值生成的。数据框中有更多包含
我的数据框是这样的: userid codeassigned timestamp 15 553938
我想从一个非常奇怪的字符串中解析出一个 ISIN,我的代码如下所示: > df dput(df) structure(list(ID = c(1L, 2L, 4L, 2L, 3L, 24L), VA
我对 isin() 函数准确性有一些问题。 我的 DataFrame 中有 abc 许多 ID: df = DataFrame[DataFrame['id'].isin(IDs)] 但是结果: pri
我有一本字典,我想使用该字典对 df 中的新列进行分类。 df 中的 Value 列应该与字典中的值进行比较。 df 中的新列应该是与值关联的键。 d = {'Car':['1','2','3'],
我正在尝试检查另一个数据框中是否存在行。我没有加入/合并,因为它会产生重复,然后需要过滤掉重复可能也会过滤掉我想要保留的实际重复。 示例: table1 = pd.DataFrame({'a':[1,
我正在尝试使用 Java 中的列表来过滤 Spark DataFrame。 java.util.List selected = ....; DataFrame result = df.filter(d
我有两个数据框。 Dataframe A 有一列由 list ids(命名项)值组成。数据框 B 有一列 int id 值(命名为 id)。 数据框 A: date | items
我正在尝试将 .isin 与 ~ 一起使用,这样我就可以根据 2 个数据集中的多列获取唯一行的列表。 所以,我有 2 个 9 行的数据集:df1 是底部,df2 是顶部(抱歉,但我无法让它在下面同时显
d = {'Dates':[pd.Timestamp('2013-01-02'), pd.Timestamp('2013-01-03'), pd
isin() 给我奇怪的结果。我创建了以下 DataFrame: import pandas as pd import numpy as np test=pd.DataFrame({'1': np.l
我有一个非常简单的场景,我想测试二维数组的两个元素是否(单独)是更大数组的成员 - 例如: full_array = np.array(['A','B','C','D','E','F']) sub_a
我可以帮助您使用 ISIN pandas 函数。基本上,我需要根据不同的标准按年汇总数据框中的数据。问题是我需要对数据进行许多聚合(例如国家名称、资助计划等)。为了方便起见,我试图在 for 循环中执
这是我的模型: type: { type: Sequelize.STRING, defaultValue: 'text', allowNull: fal
我有两个数组: a = np.array([[1, 2], [3, 4], [5, 6]]) b = np.array([[1, 1, 1, 3, 3], [1, 2, 4
这是一个例子 创建一个包含 100M 相同行的表: >>> df = pd.DataFrame([('20170101', 'TULIP', 'FLOWER')] * 100000000, colum
这个问题已经有答案了: check for identical rows in different numpy arrays (7 个回答) 已关闭 2 年前。 我有两个数组: A = np.arra
假设我有以下两个数据框: df = pd.DataFrame({'col1':['a','b', 'c'], 'col2': ['q', 'w', 'e']}) df1 = pd.DataFrame(
这个问题已经有答案了: check for identical rows in different numpy arrays (7 个回答) 已关闭 2 年前。 我有两个数组: A = np.arra
假设我有以下两个数据框: df = pd.DataFrame({'col1':['a','b', 'c'], 'col2': ['q', 'w', 'e']}) df1 = pd.DataFrame(
我是一名优秀的程序员,十分优秀!