根据第二个列表中的值分隔一个列表

时间:2018-06-27 21:11:12

标签: python

X:列表列表,其中每个列表元素对应于Y中的标签

Y:标签的二进制列表(值为1或0)

我想根据Y中相应索引处的值提取X中的元素,如下所示:

好= X的值,其中Y中的标签/值是1
不好= X的值,其中Y的标签/值是0

我对使用Python进行子设置还是很陌生,并且不确定如何做到这一点。

4 个答案:

答案 0 :(得分:1)

如果关于您的问题的某些事情自然而然地需要这样做,那就是用一堆布尔切片而不是循环,这可能表明您应该使用NumPy:

>>> x = np.array([[1,2,3], [4,5,6], [7,8,9]])
>>> y = np.array([1, 0, 1])
>>> y == 1
array([ True, False,  True])
>>> x[y == 1]
array([[1, 2, 3],
       [7, 8, 9]])

另一方面,如果这在循环方面确实有意义,那么要做的一件简单的事情就是详细地编写循环语句,然后才想出如何将其转换为整洁的列表理解。

因此,让我们将英语描述翻译成Python。

首先,我们要在X的值和Y的对应值之间循环。这就是zip的作用。所以:

for x, y in zip(X, Y):

现在,如果x等于1,则y是好的。

for x, y in zip(X, Y):
    if y == 1:
        # x is good

我们想要使用良好的x值是将它们收集到一个新列表中。所以:

good = []
for x, y in zip(X, Y):
    if y == 1:
        good.append(x)

这完全符合列表理解的模式:您创建一个空列表,然后在其下有一个for,其中包含零个或多个嵌套的for和/或if语句,以及列表底部的append。所以:

good = [x for x, y in zip(X, Y) if y == 1]

或者,由于1是真实的,而0是虚假的:

good = [x for x, y in zip(X, Y) if y]

看起来很普通,可以包装为一个函数:

def compress(X, Y):
    return [x for x, y in zip(X, Y) if y]

最后,许多类似的有趣循环模式已经包装在itertools中的函数中;或者,如果没有,则封装在more_itertoolstoolz等第三方库中。因此,值得对它们进行扫描,以查找是否有已经完全满足您需要的功能。而且,实际上,有:

def compress(data, selectors):
    # compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F
    return (d for d, s in zip(data, selectors) if s)

因此,您可以使用它:

import itertools
good = list(itertools.compress(X, Y))

但是,即使最终最终使用itertools,仍然值得学习如何自己编写这些东西。

答案 1 :(得分:0)

list(itertools.compress(X, Y))将为您列出好名单。 list(itertools.compress(X, [not a for a in Y]))会为您列出不良列表。

答案 2 :(得分:0)

X = [[9, 8, 7, 6], [5, 4, 3, 2], [10, 11, 12, 13]]
Y = [1, 0, 0]

good = []
bad = []
for i in range(0, len(Y)):

    if Y[i] == 1:
        good.append(X[i])

    else:
        bad.append(X[i])

现在只需打印出列表goodbad

答案 3 :(得分:0)

您可以简单地将Y视为所需分区的索引列表。

xs = [[],[]]

for a, b in zip(X, Y):
    xs[b].append(a)

bad, good = xs