Python 对于一个数组中的每个标签,将另一个数组中的前k个引用设置为False
我有两个(排序)数组,A和B,长度不同,每个数组都包含重复多次的唯一标签。 A中每个标签的计数小于或等于B中的计数。 A中的所有标签将显示在B中,但B中的某些标签不会显示在A中 我需要一个与B长度相同的对象,其中,对于A中的每个标签Python 对于一个数组中的每个标签,将另一个数组中的前k个引用设置为False,python,numpy,Python,Numpy,我有两个(排序)数组,A和B,长度不同,每个数组都包含重复多次的唯一标签。 A中每个标签的计数小于或等于B中的计数。 A中的所有标签将显示在B中,但B中的某些标签不会显示在A中 我需要一个与B长度相同的对象,其中,对于A中的每个标签I(出现k_I次),B中标签I的第一次出现k_I需要设置为False。 其余元素应为True 下面的代码提供了我需要的内容,但如果A和B很大,这可能需要很长时间: import numpy as np # The labels and their frequency
I
(出现k_I
次),B中标签I
的第一次出现k_I
需要设置为False
。
其余元素应为True
下面的代码提供了我需要的内容,但如果A和B很大,这可能需要很长时间:
import numpy as np
# The labels and their frequency
A = np.array((1,1,2,2,3,4,4,4))
B = np.array((1,1,1,1,1,2,2,3,3,4,4,4,4,4,5,5))
A_uniq, A_count = np.unique(A, return_counts = True)
new_ind = np.ones(B.shape, dtype = bool)
for i in range(len(A_uniq)):
new_ind[np.where(B == A_uniq[i])[0][:A_count[i]]] = False
print(new_ind)
#[False False True True True False False False True False False False
# True True True True]
有没有更快或更有效的方法?我觉得我可能错过了一些明显的广播或矢量化解决方案。这是一个带有
np.searchsorted的解决方案。
-
idx = np.searchsorted(B, A_uniq)
id_ar = np.zeros(len(B),dtype=int)
id_ar[idx] = 1
id_ar[A_count+idx] -= 1
out = id_ar.cumsum()==0
我们可以进一步优化,使用排序性质来计算A_uniq,A_count
,而不是像这样使用np.unique
-
mask_A = np.r_[True,A[:-1]!=A[1:],True]
A_uniq, A_count = A[mask_A[:-1]], np.diff(np.flatnonzero(mask_A))
此解决方案受@Divakar的启发,使用: 输出
[False False True True True False False False True False False False
True True True True]
这样做的目的是找到A
的每个元素的插入位置,因为相等的元素将具有相同的插入位置,您必须将每个元素移动一个,从而得到groupby。然后创建一个True
数组,并将索引的值设置为False
如果可以使用pandas
,请按如下方式计算索引:
values = np.searchsorted(B, A)
indices = pd.Series(values).groupby(values).cumcount() + values
没有numpy的例子
A = [1,1,2,2,3,4,4,4]
B = [1,1,1,1,1,2,2,3,3,4,4,4,4,4,5,5]
a_i = b_i = 0
while a_i < len(A):
if A[a_i] == B[b_i]:
a_i += 1
B[b_i] = False
else:
B[b_i] = True
b_i += 1
# fill the rest of B with True
B[b_i:] = [True] * (len(B) - b_i)
# [False, False, True, True, True, False, False, False, True, False, False, False, True, True, True, True]
A=[1,1,2,2,3,4,4]
B=[1,1,1,1,2,2,3,3,4,4,4,4,5]
a_i=b_i=0
而a_i
A = [1,1,2,2,3,4,4,4]
B = [1,1,1,1,1,2,2,3,3,4,4,4,4,4,5,5]
a_i = b_i = 0
while a_i < len(A):
if A[a_i] == B[b_i]:
a_i += 1
B[b_i] = False
else:
B[b_i] = True
b_i += 1
# fill the rest of B with True
B[b_i:] = [True] * (len(B) - b_i)
# [False, False, True, True, True, False, False, False, True, False, False, False, True, True, True, True]