在更新一个大熊猫数据帧,而按行连续迭代在更新一个大熊猫数据帧,而按行连续迭代(Update a da

2019-05-12 17:46发布

我有一个看起来像这样的熊猫数据帧(它的一个相当大的一个)

           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

这些方法似乎都不工作。 我没有看到在数据帧更新的值。

Answer 1:

您可以使用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循环的情况下,你需要的这里没有显示的东西的行值原件。

更新

df.set_value(),因为0.21.0可以使用df.at(版本已弃用),而不是:

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


Answer 2:

熊猫数据框对象应被认为是系列的系列。 换句话说,你应该在列的角度来考虑它。 之所以这样,是很重要的,因为当你使用pd.DataFrame.iterrows您是通过行作为系列迭代。 但这些都不是该数据帧存储系列,所以他们是为您创建,而你迭代的新系列。 这意味着,当你尝试给他们寿,这些编辑不会最终反映在原始数据帧。

好了,现在就是出路:我们该怎么办?

在此之前后的建议包括:

  1. pd.DataFrame.set_value被弃用的熊猫版0.21
  2. pd.DataFrame.ix被弃用
  3. pd.DataFrame.loc是好的,但可以在阵列索引工作 ,你可以做的更好

我的建议
使用pd.DataFrame.at

for i in df.index:
    if <something>:
        df.at[i, 'ifor'] = x
    else:
        df.at[i, 'ifor'] = y

你甚至可以将它更改为:

for i in df.index:
    df.at[i, 'ifor'] = x if <something> else y

回应发表评论

如果我需要什么使用上一行的值如果条件?

for i in range(1, len(df) + 1):
    j = df.columns.get_loc('ifor')
    if <something>:
        df.iat[i - 1, j] = x
    else:
        df.iat[i - 1, j] = y


Answer 3:

可以使用的方法是itertuples()它遍历数据帧行作为namedtuples,具有索引值作为元组的第一个元素。 并且它与比较多快得多iterrows() 对于itertuples()row包含其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

感谢@SantiStSupery, 使用.at快得多 。



Answer 4:

你应该分配值df.ix[i, 'exp']=Xdf.loc[i, 'exp']=X代替df.ix[i]['ifor'] = x

否则,您正在使用的视图,并应该得到一个变暖:

-c:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_index,col_indexer] = value instead

但可以肯定,循环可能应更好地被一些量化的算法替换,使充分利用DataFrame作为@Phillip云建议。



Answer 5:

好吧,如果你打算无论如何迭代,为什么不使用所有,最简单的方法df['Column'].values[i]

df['Column'] = ''

for i in range(len(df)):
    df['Column'].values[i] = something/update/new_value

或者,如果你想在新值与旧的或类似的东西比较,为什么不将其存储在一个列表中,然后在末尾添加。

mylist, df['Column'] = [], ''

for <condition>:
    mylist.append(something/update/new_value)

df['Column'] = mylist


Answer 6:

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


Answer 7:

从增量列的最大数量。 例如 :

df1 = [sort_ID, Column1,Column2]
print(df1)

我的输出:

Sort_ID Column1 Column2
12         a    e
45         b    f
65         c    g
78         d    h

MAX = df1['Sort_ID'].max() #This returns my Max Number 

现在,我需要创造一个DF2列,并填写其递增MAX列值。

Sort_ID Column1 Column2
79      a1       e1
80      b1       f1
81      c1       g1
82      d1       h1

注:DF2最初将只包含列1和列2。 我们需要的MAX从DF1要创建的Sortid列和增量。



文章来源: Update a dataframe in pandas while iterating row by row