在旧数据帧上使用apply函数时如何返回新数据框?

时间:2015-10-19 03:35:20

标签: python pandas dataframe

如何在旧数据帧上使用apply函数返回新数据框?

输入数据(df):

预订rolling_mean rolling_std_dev
ds city
2013-01-01 City_2 69 NaN NaN
2013-01-02 City_2 101 NaN NaN
2013-01-03 City_2 134 101.333333 32.501282
2013-01-04 City_2 155 130.000000 27.221315
2013-01-05 City_2 104 131.000000 25.632011

代码:

def f1(x):
    if (math.isnan(x.bookings) or math.isnan(x.rolling_mean) or math.isnan(x.rolling_std_dev)):
        print "Not enough information"
    elif abs(x.bookings-x.rolling_mean) > (2*x.rolling_std_dev):
        print x.bookings
        print x.rolling_mean
        print x.rolling_std_dev

df.apply(lambda x: f2(x), axis = 1)

输出:

enter image description here

问题:

上面的函数正确编译,没有错误。但是,当我尝试运行它时,它不会给我我想要的输出。在elif语句之后它没有打印任何东西,但它应该。此外,我不理解在输出的打印部分之后显示所有nones的数据帧。它来自哪里?

我想要什么解决方案:

返回一个包含所有符合elif语句的行的新数据框。

1 个答案:

答案 0 :(得分:2)

当函数调用没有显式返回任何内容时,它返回None(因为所有函数调用必须在Python中返回一些内容,并且默认返回值为None,如果函数没有显式返回)。

这就是您获得所有None的数据框的原因。我不认为你可以用apply来实现你想要的,因为apply()1实际上为每一行运行函数并用返回值替换该行(当你看你的情况。)

您尝试做的事情可以使用 -

以矢量化方式实现
newdf = df.dropna()
result = newdf[(newdf['bookings'] - newdf['rolling_mean']) > (2 * newdf['rolling_std_dev'])]

说明 -

  • df.dropna() - 此函数会删除其中包含NaN值的任何行
  • 下一行对系列进行布尔比较(对每个元素进行相同的bool比较并返回一个布尔系列),然后它boolean indexing

演示(我更改了一行,以便至少有一行符合条件) -

In [50]: df
Out[50]:
                   bookings  rolling_mean  rolling_std_dev
ds         city
2013-01-01 City_2        69           NaN              NaN
2013-01-02 City_2       101           NaN              NaN
2013-01-03 City_2       134    101.333333        32.501282
2013-01-04 City_2       155    130.000000        27.221315
2013-01-05 City_2      1000    131.000000        25.632011

In [51]: newdf = df.dropna()

In [52]: result = newdf[(newdf['bookings'] - newdf['rolling_mean']) > (2 * newdf['rolling_std_dev'])]

In [53]: result
Out[53]:
                   bookings  rolling_mean  rolling_std_dev
ds         city
2013-01-05 City_2      1000           131        25.632011