【问题标题】:updating dataframe with iterrows用 iterrows 更新数据框
【发布时间】:2017-08-03 20:23:36
【问题描述】:

我想用 iterrows 逐行计算数据框中的值,如下所示:

df = pd.DataFrame([ list( range( 0, 6)) + [np.NaN] * 5, 
                    list( range(10,16)) + [np.NaN] * 5, 
                    list( range(20,26)) + [np.NaN] * 5, 
                    list( range(30,36)) + [np.NaN] * 5])

for (index, row) in df.iterrows():
    df.loc[ index, 6: 11] =  row[ 1: 6] - row [ 0] 

为什么 df 没有更新?

我什至尝试用df.loc[ index, 1: 6] - df.loc[ index, 0] 替换row[ 1: 6] - row [ 0],但它不起作用。这是一个微不足道的错误还是我没有掌握的更微妙的概念?还有什么更高效的吗?

【问题讨论】:

  • 您应该投票并接受(单击复选标记)解决您的问题的答案。这让未来的访问者清楚地知道什么对你有用,什么对他们有用。不要添加其他只是总结事情的回复。
  • @Paul H:我确实对这两个答案都投了赞成票。我收到一条消息,说我的投票已记录。虽然,因为我没有足够的声望 (

标签: python-3.x pandas dataframe updates series


【解决方案1】:

loc 的 Pandas 赋值会在赋值之前进行索引对齐。您的列名称将在这里错位。这样做:

for (index, row) in df.iterrows():
    df.loc[ index, 6: 11] =  (row[ 1: 6] - row [ 0]).values

df
Out[23]: 
   0   1   2   3   4   5    6    7    8    9    10
0   0   1   2   3   4   5  1.0  2.0  3.0  4.0  5.0
1  10  11  12  13  14  15  1.0  2.0  3.0  4.0  5.0
2  20  21  22  23  24  25  1.0  2.0  3.0  4.0  5.0
3  30  31  32  33  34  35  1.0  2.0  3.0  4.0  5.0

文档here 了解更多信息:

警告 pandas 在设置 Series 和 DataFrame 时会对齐所有 AXES .loc、.iloc 和 .ix。这不会修改 df 因为该列 对齐是在赋值之前。

【讨论】:

  • 这个答案和文档对我来说毫无意义。 “对齐”是什么意思?为什么 .loc 可以对齐,而 [] 没有?
  • loc 对齐事物,因为当您在相似的索引 df 和系列之间进行分配时,绝大多数情况下这是您所期望的。 OP 中的罪魁祸首更多的是没有定义特定于域的索引,并且索引访问是作为一种针对 df 的盲窗过滤器执行的:这是一种特殊情况。有了两个适当的索引,我将直接分配我的过滤数据,并且欢迎对齐的魔力。
【解决方案2】:

您很少需要遍历数据框。我会这样做:

import pandas
import numpy
x = numpy.array([
    list(range(0, 6)) + [numpy.NaN] * 5, 
    list(range(10, 16)) + [numpy.NaN] * 5, 
    list(range(20, 26)) + [numpy.NaN] * 5, 
    list(range(30, 36)) + [numpy.NaN] * 5
])

x[:, 6:] = x[:, 1:6] - x[:, [0]]

pandas.DataFrame(x)

给我:

     0     1     2     3     4     5    6    7    8    9    10
0   0.0   1.0   2.0   3.0   4.0   5.0  1.0  2.0  3.0  4.0  5.0
1  10.0  11.0  12.0  13.0  14.0  15.0  1.0  2.0  3.0  4.0  5.0
2  20.0  21.0  22.0  23.0  24.0  25.0  1.0  2.0  3.0  4.0  5.0
3  30.0  31.0  32.0  33.0  34.0  35.0  1.0  2.0  3.0  4.0  5.0

【讨论】:

    【解决方案3】:

    谢谢。我加了两个解决方案:

    df = pd.DataFrame([ list( range( 0, 6)) + [np.NaN] * 5, 
                        list( range(10,16)) + [np.NaN] * 5, 
                        list( range(20,26)) + [np.NaN] * 5, 
                        list( range(30,36)) + [np.NaN] * 5])
    
    df.loc[ :, 6: 11] =  (row[ 1: 6] - row [ 0]).values
    df
    
    Out[10]:
        0   1   2   3   4   5   6   7   8   9   10
    0   0   1   2   3   4   5   1.0 2.0 3.0 4.0 5.0
    1   10  11  12  13  14  15  1.0 2.0 3.0 4.0 5.0
    2   20  21  22  23  24  25  1.0 2.0 3.0 4.0 5.0
    3   30  31  32  33  34  35  1.0 2.0 3.0 4.0 5.0
    

    编辑:

    事实上这是行不通的!在我的真实示例中,存在一个问题,并且数据不是这个小示例所应该看到的。

    iterrows() 解决方案很慢(我的数据框大约为 9000*500),所以我将使用 numpy 数组解决方案。将数据框转换为 numpy 数组,进行计算并返回数据框。

    import numpy as np
    import pandas as pd
    
    df = pd.DataFrame([ list( range( 0, 6)) + [np.NaN] * 5, 
                        list( range(10,16)) + [np.NaN] * 5, 
                        list( range(20,26)) + [np.NaN] * 5, 
                        list( range(30,36)) + [np.NaN] * 5])
    x = df.as_matrix()
    x[ :, 6:] = x[ :, 1: 6] - x[ :, [ 0]]
    df = pd.DataFrame( x, columns=df.columns, index=df.index, dtype='int8')
    df
    
    Out[15]:
        0   1   2   3   4   5   6   7   8   9   10
    0   0   1   2   3   4   5   1   2   3   4   5
    1   10  11  12  13  14  15  1   2   3   4   5
    2   20  21  22  23  24  25  1   2   3   4   5
    3   30  31  32  33  34  35  1   2   3   4   5
    In [ ]:
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-07
      • 2020-11-09
      • 1970-01-01
      • 1970-01-01
      • 2020-08-25
      • 2018-09-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多