繁体   English   中英

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

[英]Replace second item in sublist with row value of 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']]

使用列表推导生成第一个元素的列表,然后使用id col zip它们:

In[32]:
list(zip([x[0] for x in L1], df['id'].tolist()))

Out[32]: [('elephant', '12'), ('zebra', '34'), ('lion', '56'), ('giraffe', '78')]

如果你坚持列表列表,你可以将上面的内容变成一个列表:

In[35]:
L2 = list(zip([x[0] for x in L1], df['id'].tolist()))
L2

Out[35]: [('elephant', '12'), ('zebra', '34'), ('lion', '56'), ('giraffe', '78')]

In[36]:
[list(x) for x in L2]

Out[36]: [['elephant', '12'], ['zebra', '34'], ['lion', '56'], ['giraffe', '78']]

一个纯粹的熊猫方法是从你的列表中构建一个df:

In[41]:
df2 = pd.DataFrame(L1)
df2

Out[41]: 
          0  1
0  elephant  0
1     zebra  1
2      lion  2
3   giraffe  3

然后concat enate它们:

In[43]:
merged = pd.concat([df,df2], axis=1)
merged

Out[43]: 
   id         0  1
0  12  elephant  0
1  34     zebra  1
2  56      lion  2
3  78   giraffe  3

然后简单地选择感兴趣的cols并调用.values返回一个np数组然后tolist

In[46]:
merged[[0,'id']].values.tolist()

Out[46]: [['elephant', '12'], ['zebra', '34'], ['lion', '56'], ['giraffe', '78']]

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

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

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

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

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

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM