大熊猫滚动申请不做任何事情

Lat*_*der 13 python pandas

我有一个像这样的DataFrame:

df2 = pd.DataFrame({'date': ['2015-01-01', '2015-01-02', '2015-01-03'],
                    'value': ['a', 'b', 'a']})

         date value
0  2015-01-01     a
1  2015-01-02     b
2  2015-01-03     a
Run Code Online (Sandbox Code Playgroud)

我试图了解如何应用自定义滚动功能.我试过这样做:

df2.rolling(2).apply(lambda x: 1)
Run Code Online (Sandbox Code Playgroud)

但这给了我原始的DataFrame:

         date value
0  2015-01-01     a
1  2015-01-02     b
2  2015-01-03     a
Run Code Online (Sandbox Code Playgroud)

如果我有一个不同的DataFrame,像这样:

df3 = pd.DataFrame({'a': [1, 2, 3], 'value': [4, 5, 6]})
Run Code Online (Sandbox Code Playgroud)

同样的滚动似乎有效:

df3.rolling(2).apply(lambda x: 1)

     a  value
0  NaN    NaN
1  1.0    1.0
2  1.0    1.0
Run Code Online (Sandbox Code Playgroud)

为什么这不适用于第一个DataFrame?

熊猫版:0.20.2

Python版本:2.7.10

更新

所以,我已经意识到df2列的是对象类型,而我的lambda函数的输出是一个整数.df3列是整数列.我假设这就是为什么apply不起作用的原因.

以下不起作用:

df2.rolling(2).apply(lambda x: 'a')
         date value
0  2015-01-01     a
1  2015-01-02     b
2  2015-01-03     a
Run Code Online (Sandbox Code Playgroud)

此外,假设我想在value滚动的基础上连接列中的字符,以便lambda函数的输出是字符串,而不是整数.以下也不起作用:

df2.rolling(2).apply(lambda x: '.'.join(x))

         date value
0  2015-01-01     a
1  2015-01-02     b
2  2015-01-03     a
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?滚动操作可以应用于pandas中的对象类型列吗?

Ste*_*uch 3

这是实现这一目标的一种方法。请注意,这rolling是方法的包装器numpy以及与这些方法相关的效率,但事实并非如此。这仅仅提供了一个类似的 api,允许在非数字列上滚动:

代码:

import pandas as pd

class MyDataFrame(pd.DataFrame):

    @property
    def _constructor(self):
        return MyDataFrame

    def rolling_object(self, window, column, default):
        return pd.concat(
            [self[column].shift(i) for i in range(window)],
            axis=1).fillna(default).T
Run Code Online (Sandbox Code Playgroud)

这将创建一个具有rolling_object方法的自定义数据框类。它与 pandas 的方式不太匹配,因为它一次只对单个列进行操作。

测试代码:

df2 = MyDataFrame({'date': ['2015-01-01', '2015-01-02', '2015-01-03'],
                   'value': ['a', 'b', 'c'],
                   'num': [1, 2, 3]
                   })

print(df2.rolling_object(2, 'value', '').apply(lambda x: '.'.join(x)))
Run Code Online (Sandbox Code Playgroud)

结果:

0     a.
1    b.a
2    c.b
dtype: object
Run Code Online (Sandbox Code Playgroud)