我定义的函数没有正确清理我的列表
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_zeroes
和 all_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]
这是我的最小工作示例:
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_zeroes
和 all_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]