将子列表中的第二项替换为dataframe

时间:2017-05-12 14:34:27

标签: python list pandas for-loop dataframe

我有一个嵌套列表,并希望用数据帧的行值替换每个子列表的第二项。这是我的数据框和列表:

import pandas as pd
mydata = [{'id' : '12'},
          {'id' : '34'},
          {'id' : '56'},
          {'id' : '78'},]
df = pd.DataFrame(mydata)

L1 = [ ['elephant',0], ['zebra',1], ['lion',2], ['giraffe',3]  ]

所需的结果是:[ ['elephant',12], ['zebra',34], ['lion',56], ['giraffe',78] ]

这是我的代码:

for i in L1:
    for j, row in df.iterrows():
        i[1] = df["id"][j] 

哪些输出:[['elephant', '78'], ['zebra', '78'], ['lion', '78'], ['giraffe','78']]

1 个答案:

答案 0 :(得分:2)

EdChum的回答当然是正确的,但对正在发生的事情几乎没有任何解释。我将解释现有代码的错误,以及相应的步骤。 (我的答案最终类似,但与Ed的不同。我没有测试哪个更有效,但可能是我的更容易理解。)

为什么你得到的结果是每个值都设置为78?你的代码确实:

for i in L1:
    for j, row in df.iterrows():
        i[1] = df["id"][j] 

这意味着,对于i中的每个L1,请浏览df中的每一行,并将i[1]设置为该行的"id"。这意味着在这种情况下,您为每个i[1]设置i 4次,并且在循环结束时,它始终是最后一个值,因此是'78'。您需要根据i[1]的当前值有选择地设置i[1]

您可以按如下方式修改循环:

for i in L1:
    i[1] = df["id"][i[1]]

这会修改每个列表i,将其第二个值设置为df["id"]的值,并带有原始i[1]个数字。这将产生你想要的结果。

但是,这不是非常pythonic。一般来说,我们试图避免python中的基本循环。最简洁的方法是使用列表理解,而不是像Ed那样复杂:

L1 = [[i[0], df["id"][i[1]]] for i in L1]

这与上面的循环相同,只是使用列表理解语法(所以它会快得多)。使用zip来实现此功能非常好,但不必要。

(注意,我的解决方案根本不使用pandas。)