列表理解有效,但不适用于循环 - 为什么?

时间:2016-08-19 17:05:47

标签: python pandas for-loop indexing list-comprehension

我对自己有点恼火,因为我无法理解为什么一个问题的解决方案有效,但另一个没有。就像在,它指出我对(基本)大熊猫的理解不足,这让我很生气!

无论如何,我的问题很简单:我有一个'坏'值列表('bad_index');这些对应于数据帧('data_clean1')上的行索引,我想删除相应的行。但是,由于值将随每个新数据集而变化,因此我不想将错误值直接插入代码中。这是我先做的事情:

bad_index = [2, 7, 8, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 29]

for i in bad_index:
    dataclean2 = dataclean1.drop([i]).reset_index(level = 0, drop = True)

但这不起作用; data_clean2与data_clean1完全相同。我的第二个想法是使用列表推导(如下所示);这很好。

bad_index = [2, 7, 8, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 29]

data_clean2 = data_clean1.drop([x for x in bad_index]).reset_index(level = 0, drop = True)

现在,为什么列表理解方法有效而不是'for'循环?我已经编写了几个月的代码,我觉得我不应该犯这些错误。

谢谢!

2 个答案:

答案 0 :(得分:8)

data_clean1.drop([x for x in bad_index]).reset_index(level = 0, drop = True)相当于将bad_index列表简单地传递给drop

data_clean1.drop(bad_index).reset_index(level = 0, drop = True)

drop接受一个列表,并删除列表中的每个索引。

您的显式for循环不起作用,因为在每次迭代中,您只是从dataclean1数据框中删除了不同的索引而不保存中间数据帧,因此在最后一次迭代{{1}只是执行的结果 dataclean2

答案 1 :(得分:1)

编辑:事实证明这不是您的问题...但如果您没有Deepspace的其他答案中提到的问题,那么您会遇到此问题

for i in bad_index:
    dataclean2 = dataclean1.drop([i]).reset_index(level = 0, drop = True)

想象你的坏指数是[1,2,3]而你的数据库是[4,5,6,7,8]

现在让我们逐步了解实际发生的事情

首字母:dataclean == [4,5,6,7,8]

loop0:i == 1 => drop index 1 ==> dataclean = [4,6,7,8]

loop1:i == 2 => drop index 2 ==> dataclean = [4,6,8]

loop2:i == 3 ==>掉落指数3 !!!!哦,没有索引3

你可以这样做而不是

for i in reversed(bad_index):
    ...

这样,如果先删除index3,它将不会影响索引1和2

但一般情况下,你不应该在迭代它时改变列表/字典