我定义的功能不是正确清理我的列表

时间:2017-04-08 14:01:52

标签: list pandas data-cleaning data-cleansing

这是我最小的工作示例:

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

我有四个列表,我想使用以下规则“清理”我的列表1:“如果list2 [i]或list3 [i]或list4 [i]中的任何一个等于零,那么我想消除list1中的项目。所以基本上我只保留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在处理数据方面非常出色。有没有办法让我和熊猫一起做?这些列表中的每一个实际上都是csv文件的列(在删除标题之后)。

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

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

2 个答案:

答案 0 :(得分:3)

这绝对是熊猫的工作:

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创建新的数据框,并且如果您想进一步操作数据,原始数据框将保持不变。

<强>更新

Per Divakar的答案(远比我原来的答案更优雅),大熊猫也可以这样做:

df = pd.DataFrame([list1, list2, list3, list4])
list1 = df.loc[0, (df[1:] != 0).all()].astype(int).tolist()

答案 1 :(得分:2)

这是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]