我想计算2x2矩阵的行列式,它是通过在Nx2矩阵上滚动大小为2的窗口来获取的。我只是使用行列式作为示例函数。一般来说,我想将一个函数应用于数据帧,这是通过为更大的数据帧加窗来实现的。
例如,这是一个2x2矩阵,我像这样计算行列式:
import pandas as pd
import numpy as np
d = pd.DataFrame({
"X": [1,2],
"Y": [3,4]
})
np.linalg.det(d)
现在,我可以通过沿着以下数据帧的轴= 0滑动大小为2的窗口来形成4个2x2矩阵:
df = pd.DataFrame({
"A": [1,2,3,4,5],
"B": [6,7,8,9,10],
})
看起来像:
A B
0 1 6
1 2 7
2 3 8
3 4 9
4 5 10
所以我会得到[-5。,-5。, - 。-5,-5。]
据我所知,pandas.DataFrame.rolling和rolling.apply只能应用于1D向量,而不是数据帧?你会怎么做?
答案 0 :(得分:6)
从数据框中提取numpy数组:
>>> array = df.values
>>> array
array([[ 1, 6],
[ 2, 7],
[ 3, 8],
[ 4, 9],
[ 5, 10]])
使用numpy的as_strided
函数创建滑动窗口视图:
>>> from numpy.lib.stride_tricks import as_strided
>>> rows, cols = array.shape
>>> row_stride, col_stride = array.strides
>>> windowed_array = as_strided(
... array,
... shape=(rows - 2 + 1, 2, cols),
... strides=(row_stride, row_stride, col_stride))
>>> windowed_array
array([[[ 1, 6],
[ 2, 7]],
[[ 2, 7],
[ 3, 8]],
[[ 3, 8],
[ 4, 9]],
[[ 4, 9],
[ 5, 10]]])
现在将您的函数应用于结果数组:
>>> np.linalg.det(windowed_array)
array([-5., -5., -5., -5.])
答案 1 :(得分:5)
#You can replace np.linalg.det with other functions as you like.
#use apply to get 'A' and 'B' from current row and next row and feed them into the function.
df.apply(lambda x: np.linalg.det(df.loc[x.name:x.name+1, 'A':'B']) if x.name <(len(df)-1) else None,axis=1)
Out[157]:
0 -5.0
1 -5.0
2 -5.0
3 -5.0
4 NaN
dtype: float64
答案 2 :(得分:2)
使用list comprehension进行自己的滚动:
s = pd.Series([np.linalg.det(df.iloc[i:i+2]) for i in range(df.shape[0]-1)])
输出:
0 -5.0
1 -5.0
2 -5.0
3 -5.0
dtype: float64
答案 3 :(得分:1)
之前已经问过这个问题。但是在您的情况下,一个简单的解决方法是:
df['A'] * df['B'].shift(-1) - df['A'].shift(-1) * df['B']
输出:
0 -5.0
1 -5.0
2 -5.0
3 -5.0
4 NaN