在不同的步骤中在python中移动数据

时间:2018-06-02 17:37:37

标签: python pandas function numpy shift

如果我使用错误的词汇表,请纠正我。我想用不同的步骤转移我的数据。我发现这个可变窗口大小为1:

import pandas as pd
import numpy as np

a=np.random.rand(30)
series=pd.DataFrame(a)
window_size = 3
series_s = series.copy()
for i in range(window_size):
    series = pd.concat([series, series_s.shift(-(i+1))], axis = 1)

series.dropna(axis=0, inplace=True)

在这里,我正在改变这种情况(点只是为了它将如何发展):

5 6  4    
6 4  3    
4 3  8    
3 8  9    
8 9  10    
9 10 .    
10 . .

我想要做的就是转移,例如2:

5 4  8
6 3  9    
4 8 10   
3 9  .    
8 10 .    
9  . .    
10 . .

我如何更改上面的代码或如何更改?

2 个答案:

答案 0 :(得分:2)

您可以做的是定义一个名为累积滞后的变量。 例如,让窗口大小= n,并且lag_rate为2,原始列将具有零滞后,第一列相对于原始列将具有滞后2,第二列将相对于第一列具有滞后4,并且第n列相对于第一列将具有2 * n的滞后

为了便于阅读,请稍微修改您的代码:

#set up the variables
a=np.random.rand(30)
df = pd.DataFrame()
df['original'] = a
window_size = 3
lag_by_rate = 2 

现在我将开始迭代window_size参数以生成新列。请注意,您应该将for循环设置为1而不是零,因为如果从零开始,则基本上复制数据框的原始列

for i in range(1, window_size):
    cum_lag = i * lag_by_rate
    col_name = 'lag_by_'+str(cum_lag)
    df[col_name] =  df.original.shift(-cum_lag)

最后我使用了dropna功能并打印头部:

df.dropna(axis=0, inplace=True)
print(df.head())

我输出的一个例子:

    original    lag_by_2    lag_by_4
0   0.595142    0.625494    0.812595
1   0.822615    0.582148    0.778157
2   0.625494    0.812595    0.693790
3   0.582148    0.778157    0.416109
4   0.812595    0.693790    0.748151

对于它的价值,你会用这种方法以显着的速度丢失数据。如果len(df)/ window_size == lag_rate的比率,则在删除N / A值后,最终会在数据帧中获得零行

在下面的评论中,我替换了您在示例中提到的值,并获得了相同的输出:

    original    lag_by_2    lag_by_4
0   5           4.0         8.0
1   6           3.0         9.0
2   4           8.0         10.0

答案 1 :(得分:2)

shift 会返回您的数据框的副本,但不会对其进行修改,因此无需创建副本。

您可以使用列表推导进一步清理代码,并使用一些代数将每列换成两列而不是一列。

x = np.random.randint(1, 10, 10)
df = pd.DataFrame(x)
dfs = [df.shift(-(2+2*i)) for i in range(3)]

pd.concat([df, *dfs], axis=1)

   0    0    0    0
0  3  1.0  3.0  8.0
1  9  1.0  6.0  8.0
2  1  3.0  8.0  1.0
3  1  6.0  8.0  9.0
4  3  8.0  1.0  NaN
5  6  8.0  9.0  NaN
6  8  1.0  NaN  NaN
7  8  9.0  NaN  NaN
8  1  NaN  NaN  NaN
9  9  NaN  NaN  NaN

这种方法确实为每个列留下了相同的列标题,您可以使用以下内容修复:

df_result.columns = range(len(df_result.columns))