用iterrows更新数据帧

时间:2017-03-13 17:43:22

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

我想计算数据框中的值,用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没有更新?

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

3 个答案:

答案 0 :(得分:3)

使用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   对齐是在赋值之前。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

THX。我把这两个解决方案加起来了:

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 [ ]: