Python 按顺序从列表中为dataframe中的多行分配多个值

Python 按顺序从列表中为dataframe中的多行分配多个值,python,list,pandas,dataframe,Python,List,Pandas,Dataframe,简单地说,我有一个abc列表,带有abc=[a,b,c,d,e] 我想为数据帧DF中的'Text'列分配这些值,这些值在'Number'列中的值为2。我知道数据帧有5行满足这个条件,例如第1行、第2行、第3行、第4行和第5行。我想要的是第1行=a、第2行=b、第3行=c、第4行=d、第5行=e中的值 我这样写代码: i=0 for row1 in range(0,len(df)): if df.iloc[row1]['Number']==2: df.set_val

简单地说,我有一个abc列表,带有
abc=[a,b,c,d,e]

我想为数据帧DF中的'Text'列分配这些值,这些值在'Number'列中的值为2。我知道数据帧有5行满足这个条件,例如第1行、第2行、第3行、第4行和第5行。我想要的是第1行=a、第2行=b、第3行=c、第4行=d、第5行=e中的值 我这样写代码:

 i=0
 for row1 in range(0,len(df)):
     if  df.iloc[row1]['Number']==2:
        df.set_value(df.index[row1], 'Text',abc[i])
        i=i+1
但我得到的是第1,2,3,4行的值,5得到相同的值e。
你们能告诉我怎么做吗。非常感谢

在不修改太多代码的情况下,我可以使用该函数而不是
I
循环。我正在使用Python3

import pandas as pd 
import numpy as np 
# create sample dataframe
abc = ['a','b','c','d','e', 'f']
data = {'Text':['foo', 'bar', 'spam', 'eggs', 'ham', 'asdf'],
        'Number':[2, 2, 5, 2, 2, 3]}
df = pd.DataFrame.from_dict(data) 
df = df[['Text', 'Number']] # reordering df
print(df)

# Original question code:
# i=0
# for row1 in range(0,len(df)):
#     if df.iloc[row1]['Number']==2:
#         df.set_value(df.index[row1], 'Text',abc[i])
#         i=i+1

# Pseudocode: 
# if row value for the column 'number' is 2:
#     set the value for the column 'text' at an index to the value for abc[index]
for idx, row1 in enumerate(range(0, len(df))):
    if df.iloc[row1]['Number'] == 2:
        df.set_value(df.index[row1], 'Text', abc[idx])
print(df)
请注意,set_值已折旧,将在将来的版本中删除

结果:

    text  number
0     a       2
1     b       2
2  spam       5
3     d       2
4     e       2
5  asdf       3

FutureWarning: set_value is deprecated and will be removed in a future release. Please use .at[] or .iat[] accessors instead

我想补充的另一件事是,首先我的列文本包含Nan值。当我应用代码索引器时,我遇到了这个错误。错误是,例如,我的DF有1000行,只有5行,列编号为2的值。所以我认为我们可以使用enumerate()here@Rive11我已经更新了我的答案来修正任何打字错误。您应该能够在一个新的.py文件中复制、粘贴和运行我的整个代码,而不会出现任何错误。收到的错误可能是因为现有DF的行数超过了列表abc的长度-这意味着for循环试图访问的索引数大于列表abc中的元素数。在本例中,您可以将
enumerate(range(0,len(df))
替换为
enumerate(range(0,len(abc))
,它只检查索引
len(abc)-1
中的行。以您的示例为例,我保留了列表abc(包含6个元素),并创建了一个包含9行的新df,其中有6行,列text中的数字为2。数据={'Text':['foo','bar','spam','egs','ham','asdf','cvddd','vfhfhhfhfhfhfhfhff','cgdd','aa','Number':[2,2,5,2,4,2,3,2,4,2]}。我使用enumerate(范围(0,len(abc))修改您的代码。结果是,列表abc中的元素“c”和“e”被删除,df中的最后两个“2”仍然没有被abc中的元素替换,因此您知道如何解决此问题吗?非常感谢您希望替换df中(最多)每一行的值,列表abc和df的长度必须相同。如果查看for循环,使用
range(0,len(abc))
只会在df中迭代到列表abc的长度。如果您的数据帧比列表长,循环将不会用与列表长度相等的索引替换超过该行的任何行。是的。这就是问题所在。但我必须使用比列表长度多得多的行的df。那么你知道我可以用别的方法来处理我的案子吗。我尝试创建新的列表B,其中包含数值为Number=2的行的位置。B=[0,1,3,5,7,9]。有什么方法可以处理两个列表吗?