过滤两个列表[List]给定一个过滤器列表[List]-按顺序保持列表



所以我有两个List[List]X,Y,我需要过滤给定的List[List]Z。Y中的值对应于X中元素的分数。我需要检查X的值是否属于Z中的过滤器,并保持Y中的分数对应于这些值。

我将用一个例子和我目前的解决方案来说明。

# Base matrixes
X = [[2,1,3,4],
[1,3,2,4],
[1,2,3,4]]
Y = [[0.2,0.1,0.9,1.0],
[0.3,0.2,0.4,0.2],
[0.8,0.6,0.5,0.2]]
Z = [[1,2,3,4],
[2,3],
[1]]
# Expected results
new_x = [[2,1,3,4],
[3,2],
[1]]
new_y = [[0.2,0.1,0.9,1.0],
[0.2,0.4],
[0.8]]

# Current solution
def find_idx(a,b):
r = []
for idx, sub_a in enumerate(a):
if sub_a in b:
r+=[idx]
return r
def filter(X, Y, Z):
X = np.asarray(X)
Y = np.asarray(Y)
Z = np.asarray(Z)

assert len(X)==len(Y)==len(Z)    
r_x = []
r_y = []
for idx, sub_filter in enumerate(Z):
x = find_idx(X[idx], Z[idx])
r_x.append(X[idx][x].tolist())
r_y.append(Y[idx][x].tolist())
return r_x, r_y

r_x, r_y = filter(X,Y,Z)

我发现使用一组列表理解可以很容易地做到这一点,但性能对于这个函数来说很重要。

有没有办法加快我找到Z中X值索引的部分,以便稍后用它们过滤X、Y?

当输入矩阵很大时,这是一种更有效的方法:

X = np.array([
[2, 1, 3, 4],
[1, 3, 2, 4],
[1, 2, 3, 4],
])
Y = np.array([
[0.2, 0.1, 0.9, 1.0],
[0.3, 0.2, 0.4, 0.2],
[0.8, 0.6, 0.5, 0.2],
])
Z = [[1, 2, 3, 4],
[2, 3],
[1],
]
mask = np.zeros(X.shape)
new_x = []
new_y = []
for i, z_row in enumerate(Z):
mask = np.isin(X[i], z_row)
new_x.append(X[i][mask].tolist())
new_y.append(Y[i][mask].tolist())

当我用5000x5000矩阵测试它时,它比列表理解快了大约10倍。这是因为当使用in运算符时,列表理解必须在列表z的所有元素上循环。

使用嵌套列表理解:

x_new = [[x[i-1] for i in z] for x,z in zip(X, Z)]

输出:

[[2, 1, 3, 4],
[3, 2],
[1]]
new_x = []
new_y = []
zipped_xy = [list(zip(*el)) for el in zip(X, Y)]

for idx, v in enumerate(Z):
temp_x = []
temp_y = []
for x, y in zipped_xy[idx]:
if x in v:
temp_x.append(x)
temp_y.append(y)
new_x.append(temp_x)
new_y.append(temp_y)
print(new_x)
print(new_y)
# [[2, 1, 3, 4], [3, 2], [1]]
# [[0.2, 0.1, 0.9, 1.0], [0.2, 0.4], [0.8]]

相关内容

最新更新