我有一个熊猫数据帧,看起来像这样(它非常大)

           date      exer exp     ifor         mat  
1092  2014-03-17  American   M  528.205  2014-04-19 
1093  2014-03-17  American   M  528.205  2014-04-19 
1094  2014-03-17  American   M  528.205  2014-04-19 
1095  2014-03-17  American   M  528.205  2014-04-19    
1096  2014-03-17  American   M  528.205  2014-05-17 

现在我想逐行迭代,当我遍历每一行时,ifor的值 在每一行可以改变取决于某些条件,我需要查找另一个数据框架。

现在,我如何在迭代时更新它。 试过几招,都没用。

for i, row in df.iterrows():
    if <something>:
        row['ifor'] = x
    else:
        row['ifor'] = y

    df.ix[i]['ifor'] = x

这些方法似乎都不起作用。我没有在数据框架中看到更新的值。


当前回答

列表理解可以是一个选项。

df['new_column'] = [your_func(x) for x in df['column']]

这将遍历列df['column'],使用来自df['column']的值调用函数your_func,并为新列df['new_column']中的行赋值。

请不要忘记创建一个函数。

其他回答

列表理解可以是一个选项。

df['new_column'] = [your_func(x) for x in df['column']]

这将遍历列df['column'],使用来自df['column']的值调用函数your_func,并为新列df['new_column']中的行赋值。

请不要忘记创建一个函数。

最好使用df.apply() -来使用lambda函数

df["ifor"] = df.apply(lambda x: {value} if {condition} else x["ifor"], axis=1)

你应该用df来赋值。ix[i, 'exp']=X或df。loc[i, 'exp']=X而不是df。Ix [i]['ifor'] = x。

否则,你正在处理一个视图,并且应该得到一个温暖:

-c:1: SettingWithCopyWarning:一个值正在试图从一个DataFrame的切片副本上设置。 尝试使用.loc[row_index,col_indexer] = value代替

但可以肯定的是,循环应该被一些矢量化算法所取代,以充分利用@Phillip Cloud所建议的DataFrame。

你可以使用df.at:

for i, row in df.iterrows():
    ifor_val = something
    if <condition>:
        ifor_val = something_else
    df.at[i,'ifor'] = ifor_val

对于0.21.0之前的版本,使用df.set_value:

for i, row in df.iterrows():
    ifor_val = something
    if <condition>:
        ifor_val = something_else
    df.set_value(i,'ifor',ifor_val)

如果你不需要行值,你可以简单地遍历df的索引,但我保留了原始的for循环,以防你需要行值来处理这里没有显示的东西。

你可以使用的一个方法是itertuples(),它迭代DataFrame行作为命名元组,索引值作为元组的第一个元素。与iterrows()相比,它要快得多。对于itertuples(),每行在DataFrame中包含它的Index,您可以使用loc来设置该值。

for row in df.itertuples():
    if <something>:
        df.at[row.Index, 'ifor'] = x
    else:
        df.at[row.Index, 'ifor'] = x

    df.loc[row.Index, 'ifor'] = x

在大多数情况下,itertuples()比iat或at快。

谢谢@SantiStSupery,使用。at比loc快得多。