为什么这个函数在pandas数据帧上出错后不“接受”?

2024-09-29 01:25:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个带有时间戳的温度和风速值的数据帧,以及一个将这些值转换为“风寒”的函数。我使用iterrows在每一行上运行该函数,并希望通过一个漂亮的“风寒”列得到一个数据框。在

然而,虽然它看起来像是在工作,而且实际上至少“工作”过一次,但我似乎不能始终如一地复制它。总的来说,我觉得这是我在数据帧结构方面缺少的东西,但我希望有人能帮上忙。在

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

所以我在bigdf中添加了一个'windchill'列,并用NaN预填充。在

^{pr2}$

然后我尝试遍历这些行,以添加实际的风寒。在

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

正如您所说,新值显示为将应用于“风寒”列。以下是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

但是,当我再次查看数据帧时,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

更奇怪的是,已经起过一两次作用了,我不知道我做了什么不同。在

我必须承认,我对pandas的内部工作原理不是特别熟悉,而且对索引等也很困惑,所以我觉得我可能在这里遗漏了一些非常基本的东西(或者很难做到这一点)。在

谢谢!在


Tags: 数据函数innantemprowspeedwind
3条回答

您可以使用^{}来执行此操作:

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

一。在

为了进一步解释您产生困惑的原因,我认为这是因为行变量是df的copies rather than views,因此更改不会传播:

^{pr2}$

我们看到它成功地对copy进行了更改,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

但是它们不会更新到数据帧:

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

以下内容也保持df不变:

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

In [25]: row['Day'] = 2

然而,如果我们真的采取了观点:(我们将看到变化df

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

In [27]: row['Day'] = 3

Returning a view versus a copy (in the docs)。在

我想说你不需要任何显式循环。希望下面的内容能满足您的需要

bigdf = pd.DataFrame({'Temperature': [30.27, 30.21, 31.81], 'Wind Speed': [5.27, 4.83, 6.09]})

def windchill(temp, wind):
    "compute the wind chill given two pandas series temp and wind"
    tomodify = (temp<=50) & (wind>3) #check which values need to be modified
    t = temp.copy()  #create a new series
    # change only the values that need modification
    t[tomodify] = 35.74 + 0.6215*temp[tomodify] - 35.75*wind[tomodify]**0.16 +
        0.4275*temp[tomodify]*wind[tomodify]**0.16
    return t

bigdf['Wind Chill'] = windchill(bigdf['Temperature'], bigdf['Wind Speed'])

bigdf

   Temperature  Wind Speed  Wind Chill
0        30.27        5.27   24.794589
1        30.21        4.83   25.136527
2        31.81        6.09   25.934114

ps:这个windchill的实现也适用于numpy数组。在

试试看:

bigdf['Wind Chill'] = bigdf.apply(lambda x: windchill(x['Temperature'], x['Wind Speed']), axis=1)

使用简单的windchill函数一次性获取整个数据帧。在

相关问题 更多 >