为什么在我对庞大的数据框架进行修改后,这个函数"没有"?

wim*_*msy 3 python pandas

我有一个带时间戳温度和风速值的DataFrame,以及将它们转换成"风寒"的功能.我正在使用iterrows在每一行上运行该函数,并希望通过一个漂亮的"Wind Chill"列获得一个DataFrame.

然而,虽然它似乎正在经历,并且实际上至少已经"工作"了一次,但我似乎无法一致地复制它.我觉得这是我对DataFrames结构缺失的一般情况,但我希望有人可以提供帮助.

In [28]: bigdf.head()
Out[28]: 


                           Day  Temperature  Wind Speed  Year
2003-03-01 06:00:00-05:00  1    30.27        5.27        2003
2003-03-01 07:00:00-05:00  1    30.21        4.83        2003
2003-03-01 08:00:00-05:00  1    31.81        6.09        2003
2003-03-01 09:00:00-05:00  1    34.04        6.61        2003
2003-03-01 10:00:00-05:00  1    35.31        6.97        2003
Run Code Online (Sandbox Code Playgroud)

所以我添加了一个'Wind Chill'列bigdf并预填充NaN.

In [29]: bigdf['Wind Chill'] = NaN
Run Code Online (Sandbox Code Playgroud)

然后我尝试迭代行,添加实际的风寒.

In [30]: for row_index, row in bigdf[:5].iterrows():
    ...:     row['Wind Chill'] = windchill(row['Temperature'], row['Wind Speed'])
    ...:     print row['Wind Chill']
    ...:
24.7945889994
25.1365267133
25.934114012
28.2194307516
29.5051046953
Run Code Online (Sandbox Code Playgroud)

正如您所说,新值似乎应用于"Wind Chill"列.这是windchill函数,以防万一有助于:

def windchill(temp, wind):
    if temp>50 or wind<=3:
        return temp
    else:
        return 35.74 + 0.6215*temp - 35.75*wind**0.16 + 0.4275*temp*wind**0.16
Run Code Online (Sandbox Code Playgroud)

但是,当我再次查看DataFrame时,NaN仍然存在:

In [31]: bigdf.head()
Out[31]: 

                           Day  Temperature  Wind Speed  Year  Wind Chill
2003-03-01 06:00:00-05:00  1    30.27        5.27        2003  NaN
2003-03-01 07:00:00-05:00  1    30.21        4.83        2003  NaN
2003-03-01 08:00:00-05:00  1    31.81        6.09        2003  NaN
2003-03-01 09:00:00-05:00  1    34.04        6.61        2003  NaN
2003-03-01 10:00:00-05:00  1    35.31        6.97        2003  NaN
Run Code Online (Sandbox Code Playgroud)

甚至更奇怪的是,它已经工作过一次或两次,而且我不知道我做了什么不同的事情.

我必须承认我并不是特别熟悉大熊猫的内部工作方式,并且对索引等感到困惑,所以我觉得我可能在这里遗漏了一些非常基本的东西(或者很难做到这一点).

谢谢!

And*_*den 9

你可以apply这样做:

In [11]: df.apply(lambda row: windchill(row['Temperature'], row['Wind Speed']),
                 axis=1)
Out[11]:
2003-03-01 06:00:00-05:00    24.794589
2003-03-01 07:00:00-05:00    25.136527
2003-03-01 08:00:00-05:00    25.934114
2003-03-01 09:00:00-05:00    28.219431
2003-03-01 10:00:00-05:00    29.505105

In [12]: df['Wind Chill'] = df.apply(lambda row: windchill(row['Temperature'], row['Wind Speed']),
                                    axis=1)

In [13]: df
Out[13]:
                           Day  Temperature  Wind Speed  Year  Wind Chill
2003-03-01 06:00:00-05:00    1        30.27        5.27  2003   24.794589
2003-03-01 07:00:00-05:00    1        30.21        4.83  2003   25.136527
2003-03-01 08:00:00-05:00    1        31.81        6.09  2003   25.934114
2003-03-01 09:00:00-05:00    1        34.04        6.61  2003   28.219431
2003-03-01 10:00:00-05:00    1        35.31        6.97  2003   29.505105
Run Code Online (Sandbox Code Playgroud)

.

为了扩大您混淆的原因,我认为这源于行变量是副本而不是 df的视图这一事实,因此更改不会传播:

In [21]: for _, row in df.iterrows(): row['Day'] = 2
Run Code Online (Sandbox Code Playgroud)

我们看到它正在成功地对副本进行更改,即row变量:

In [22]: row
Out[22]:
Day               2.00
Temperature      35.31
Wind Speed        6.97
Year           2003.00
Name: 2003-03-01 10:00:00-05:00
Run Code Online (Sandbox Code Playgroud)

他们不会更新到DataFrame:

In [23]: df
Out[23]:
                           Day  Temperature  Wind Speed  Year
2003-03-01 06:00:00-05:00    1        30.27        5.27  2003
2003-03-01 07:00:00-05:00    1        30.21        4.83  2003
2003-03-01 08:00:00-05:00    1        31.81        6.09  2003
2003-03-01 09:00:00-05:00    1        34.04        6.61  2003
2003-03-01 10:00:00-05:00    1        35.31        6.97  2003
Run Code Online (Sandbox Code Playgroud)

以下内容也df保持不变:

In [24]: row = df.ix[0]  # also a copy

In [25]: row['Day'] = 2
Run Code Online (Sandbox Code Playgroud)

如果我们确实采取了观点 :(我们会看到变化 df.)

In [26]: row = df.ix[2:3]  # this one's a view

In [27]: row['Day'] = 3
Run Code Online (Sandbox Code Playgroud)

请参阅返回视图与副本(在文档中).