我定义的函数没有正确清理我的列表

Function I defined is not cleaning my list properly

这是我的最小工作示例:

list1 = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] #len = 21
list2 = [1,1,1,0,1,0,0,1,0,1,1,0,1,0,1,0,0,0,1,1,0]     #len = 21
list3 = [0,0,1,0,1,1,0,1,0,1,0,1,1,1,0,1,0,1,1,1,1]  #len = 21
list4 = [1,0,0,1,1,0,0,0,0,1,0,1,1,1,1,0,1,0,1,0,1]   #len = 21

我有四个列表,我想 "clean" 我的列表 1 使用以下规则:“如果 list2[i] 或 list3[i] 或 list4[i] 中的任何一个等于零,则我想从 list1 中删除项目 I。所以基本上我只保留 list1 的那些元素,以便其他列表都在那里。

这是我为解决这个问题而写的函数

def clean(list1, list2,list3,list4):
    for i in range(len(list2)):
        if (list2[i]==0 or list3[i]==0 or list4[i]==0):
            list1.pop(i)
    return list1

但是它不起作用。如果你应用它,它会给出错误

Traceback (most recent call last):line 68, in clean list1.pop(I)

IndexError: pop index out of range

我做错了什么?另外,有人告诉我 Pandas 非常擅长处理数据。有什么方法可以用 Pandas 做到吗?这些列表中的每一个实际上都是 csv 文件的列(在删除标题之后)。

编辑 例如最后我想得到:list1 = [4,9,11,15]

我认为主要问题是在每次迭代时,当我弹出元素时,该元素的所有后继者的索引都会改变!而且,列表的总长度发生变化,因此 pop() 中的索引太大。所以希望我可以使用另一种策略或功能

这绝对是 pandas 的工作:

import pandas as pd

df = pd.DataFrame({
        'l1':list1,
        'l2':list2,
        'l3':list3,
        'l4':list4
        })

no_zeroes = df.loc[(df['l2'] != 0) & (df['l3'] != 0) & (df['l4'] != 0)]

其中 df.loc[...] 获取完整的数据帧,然后根据提供的条件对其进行过滤。在此示例中,您的标准是仅保留 l2、l3 和 l3 不为零 (!= 0) 的项目。

给你一个 pandas 数据框:

    l1  l2  l3  l4
4    4   1   1   1
9    9   1   1   1
12  12   1   1   1
18  18   1   1   1

或者如果您只需要 list1:

list1 = df['l1'].tolist()

如果您希望条件位于所有其他列为 1 的位置,则使用:

all_ones = df.loc[(df['l2'] == 1) & (df['l3'] == 1) & (df['l4'] == 1)]

请注意,我正在为 no_zeroesall_ones 创建新的数据帧,如果您想进一步操作数据,原始数据帧将保持不变。

更新:

根据 Divakar 的回答(比我原来的回答优雅得多),在 pandas:

中也可以做同样的事情
df = pd.DataFrame([list1, list2, list3, list4])
list1 = df.loc[0, (df[1:] != 0).all()].astype(int).tolist()

这是 NumPy -

的一种方法
import numpy as np

mask = (np.asarray(list2)==1) & (np.asarray(list3)==1) & (np.asarray(list4)==1)
out = np.asarray(list1)[mask].tolist()

这是 NumPy 的另一种方法,它将这些列表堆叠成行以形成 2D 数组,从而大大简化了事情 -

arr = np.vstack((list1, list2, list3, list4))
out = arr[0,(arr[1:] == 1).all(0)].tolist()

样本运行-

In [165]: arr = np.vstack((list1, list2, list3, list4))

In [166]: print arr
[[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20]
 [ 1  1  1  0  1  0  0  1  0  1  1  0  1  0  1  0  0  0  1  1  0]
 [ 0  0  1  0  1  1  0  1  0  1  0  1  1  1  0  1  0  1  1  1  1]
 [ 1  0  0  1  1  0  0  0  0  1  0  1  1  1  1  0  1  0  1  0  1]]

In [167]: arr[0,(arr[1:] == 1).all(0)].tolist()
Out[167]: [4, 9, 12, 18]