Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 熊猫滚动物体是如何工作的?_Python_Pandas_Numpy_Dataframe_Cython - Fatal编程技术网

Python 熊猫滚动物体是如何工作的?

Python 熊猫滚动物体是如何工作的?,python,pandas,numpy,dataframe,cython,Python,Pandas,Numpy,Dataframe,Cython,编辑:我将这个问题浓缩,因为它可能太复杂了。问题的要点用黑体字写在下面 我想了解更多关于使用或时实际创建的对象的信息: 此处rwindows将采用1d或2dndarray并构建与指定窗口大小相等的滚动“块”(如下所示)一个.rolling对象与下面的ndarray输出相比如何?它是一个迭代器,为每个块存储了某些属性吗?或者完全是别的什么?我尝试过在对象上使用属性/方法(如\u dict\u和\u get\u index()。我也在熊猫身上看到过一种方法——它是否与stripped方法相似 # a

编辑:我将这个问题浓缩,因为它可能太复杂了。问题的要点用黑体字写在下面

我想了解更多关于使用或时实际创建的对象的信息:

此处
rwindows
将采用1d或2d
ndarray
并构建与指定窗口大小相等的滚动“块”(如下所示)一个
.rolling
对象与下面的
ndarray
输出相比如何?
它是一个迭代器,为每个块存储了某些属性吗?或者完全是别的什么?我尝试过在对象上使用属性/方法(如
\u dict\u
\u get\u index()。我也在熊猫身上看到过一种方法——它是否与
stripped
方法相似

# as_strided version

a = np.arange(5)
print(rwindows(a, 3))           # 1d input
[[0 1 2]
 [1 2 3]
 [2 3 4]]

b = np.arange(10).reshape(5,2)
print(rwindows(b, 4))           # 2d input
[[[0 1]
  [2 3]
  [4 5]
  [6 7]]

 [[2 3]
  [4 5]
  [6 7]
  [8 9]]]
第二部分,额外学分 使用上述NumPy方法(OLS实现)是必要的,因为必须在

从ndarray输入生成单个值*args和**kwargs是 传递给函数

所以这个参数不能是另一个滚动对象。即

def prod(a, b):
    return a * b
df.rolling(3).apply(prod, args=((df + 2).rolling(3),))
-----------------------------------------------------------------------
...
TypeError: unsupported operand type(s) for *: 'float' and 'Rolling'

这就是我上面的问题的来源。为什么传递的函数必须使用NumPy数组并生成单个标量值,这与
.rolling
对象的布局有什么关系?

我建议您查看源代码,以了解rolling的具体功能。我特别建议您查看和中的
滚动
函数。从这里可以查看在指定窗口类型或默认窗口类型时使用的。最后一个继承自
\u滚动和扩展
,最终继承了
\u滚动
\u窗口

也就是说,我会给我的两分钱:熊猫的整个滚动机制依赖于numpy功能。尤其是在熊猫身上。它与cython模块一起使用。在你的系列中,出现了聚合滚动窗口。对于典型的聚合函数,它可以有效地为您处理它们,但是对于自定义函数(使用
apply()
),它使用了一个位于
windows.pyx
中的

pandas中的滚动功能在pandas数据帧列上独立运行。它不是一个,并且是延迟加载的,这意味着在对其应用聚合函数之前不会计算任何内容。真正应用数据滚动窗口的函数直到聚合完成之前才被使用

造成混淆的一个原因可能是您将滚动对象视为一个数据帧。(您已在上一个代码段中将滚动对象命名为
df
)。事实并非如此。它是一个对象,可以通过在它所包含的窗口逻辑上应用聚合来生成数据帧

您提供的lambda将应用于新数据帧的每个单元。它在旧数据帧中向后(沿每列)获取一个窗口,并将其聚合到新数据帧中的一个单元格中。聚合可以是像
sum
mean
、定制的东西等等,在一些窗口大小上,比如3。以下是一些例子:

a = np.arange(5)
df = pd.DataFrame(a, columns=['a'])
df.rolling(3).mean().dropna()
。。。这也可以通过以下方式实现:

df.rolling(3).apply(np.mean).dropna()
。。。并生产:

     a
2  3.0
3  6.0
4  9.0
(第一列是索引值,在这里和下面的示例中可以忽略。)

注意我们是如何提供一个现有的numpy聚合函数的。这就是我的想法。我们应该能够提供我们想要的任何东西,只要它符合聚合函数的功能,即获取一个值向量并从中生成一个值。下面是我们创建自定义聚合函数的另一个示例,在本例中为窗口的L2范数:

df.rolling(3).apply(lambda x: np.sqrt(x.dot(x))).dropna()
如果您不熟悉lambda函数,则如下所示:

def euclidean_dist(x):
    return np.sqrt(x.dot(x))

df.rolling(3).apply(euclidean_dist).dropna()
。。。屈服:

          a
2  2.236068
3  3.741657
4  5.385165
为了确保这一点,我们可以手动检查
np.sqrt(0**2+1**2+2**2)
是否确实是
2.236068

[在最初的编辑中,在]最后一段代码中,您的代码可能比您预期的更早失败。调用
df.apply(…)
之前失败。您正在尝试将名为
df
的滚动对象添加到数字2,然后将其传递到
df.apply(…)
。滚动对象不是对其执行操作的对象。您提供的聚合函数通常也不符合聚合函数。
a
是一个包含窗口值的列表,
b
将是您传入的一个常量额外参数。如果您愿意,它可以是一个滚动对象,但通常不会是您想要做的事情。更清楚地说,这里有一点与您在原始编辑中所做的类似,但很有效:

a = np.arange(8)
df = pd.DataFrame(a, columns=['a'])
n = 4
rol = df.rolling(n)

def prod(window_list, constant_rol):
    return window_list.dot(constant_rol.sum().dropna().head(n))

rol.apply(prod, args=(rol,)).dropna()

# [92.0, 140.0, 188.0, 236.0, 284.0]
这是一个人为的例子,但我展示它是为了说明一点,你可以把你想要的任何东西作为常数传递进来,即使是你正在使用的滚动对象本身。动态部分在您的案例中是第一个参数
a
,在我的案例中是
window\u list
。以单个列表形式定义的所有窗口都会逐个传递到该函数中

根据您的后续评论,这可能是您想要的:

import numpy as np
import pandas as pd

n = 3
a = np.arange(5)
df = pd.DataFrame(a, columns=['a'])

def keep(window, windows):
    windows.append(window.copy())
    return window[-1]

windows = list()
df['a'].rolling(n).apply(keep, args=(windows,))
df = df.tail(n)
df['a_window'] = windows
将阵列/向量添加到每个滚动块,从而产生:

   a         a_window
2  2  [0.0, 1.0, 2.0]
3  3  [1.0, 2.0, 3.0]
4  4  [2.0, 3.0, 4.0]
请注意,只有在一次对一列执行此操作时,它才起作用。如果您想在将窗口存储在
中之前对其进行一些计算,请保留
,这也很好

这就是说,如果没有更多关于您正试图实现的目标的投入,就很难构建一个适合您需要的示例

如果您的最终目标是创建滞后变量的数据帧,那么我会使用
shift()

。。。给予:

   a  a-1  a-2
2  2  1.0  0.0
3  3  2.0  1.0
4  4  3.0  2.0
(也许有更好的方法,但它能完成任务。)

关于第一个代码段中的变量
b
,还记得DataFram吗
   a         a_window
2  2  [0.0, 1.0, 2.0]
3  3  [1.0, 2.0, 3.0]
4  4  [2.0, 3.0, 4.0]
import numpy as np
import pandas as pd

a = np.arange(5)

df = pd.DataFrame(a, columns=['a'])
for i in range(1,3):
    df['a-%s' % i] = df['a'].shift(i)

df.dropna()
   a  a-1  a-2
2  2  1.0  0.0
3  3  2.0  1.0
4  4  3.0  2.0
import pandas as pd

a = np.arange(50)
df = pd.DataFrame(a, columns=['a'])
df.index = pd.to_datetime('2016-01-01') + pd.to_timedelta(df['a'], 'D')
blocks, obj, index = df.rolling(4, freq='W')._create_blocks(how=None)
for b in blocks:
    print(b)
               a
a               
2016-01-03   2.0
2016-01-10   9.0
2016-01-17  16.0
2016-01-24  23.0
2016-01-31  30.0
2016-02-07  37.0
2016-02-14  44.0
2016-02-21   NaN
                a
a                
2016-01-03    NaN
2016-01-10    NaN
2016-01-17    NaN
2016-01-24   50.0
2016-01-31   78.0
2016-02-07  106.0
2016-02-14  134.0
2016-02-21    NaN
import pandas as pd
a = np.arange(5)
df = pd.DataFrame(a, columns=['a'])
blocks, obj, index = df.rolling(3)._create_blocks(how=None)

for b in blocks:
    print(b)
            a
a            
2016-01-01  0
2016-01-02  1
2016-01-03  2
2016-01-04  3
2016-01-05  4