Python在DataFame中添加列,并基于之前的3行滚动窗口。

问题描述 投票:1回答:1

我有一个这样的数据框。

original = pd.DataFrame(np.random.randint(0,100,size=(10, 3)), columns=["P1_day", "P1_week", "P1_month"])
print(original)

   P1_day  P1_week  P1_month
0      50       17        55
1      45        3        10
2      93       79        84
3      99       38        33
4      44       35        35
5      25       43        87
6      38       88        56
7      20       66         6
8       4       23         6
9      39       75         3

我需要从第三行开始生成一个新的数据框。original 数据框架,并在滚动窗口的基础上添加新的9列,这些列定义为前3行的相应前缀。[_0,_1, _2]. 所以,这是索引[0,1,2]的行,从 original 数据框架。例如,接下来的3列将来自于数据框架的 original.iloc[0]后面的3列将从。original.iloc[1],最后3列将来自于 "我"。original.iloc[2]

我尝试用下面的代码来解决这个问题。

    subset_shifted = original[["P1_day", "P1_week", "P1_month"]].shift(3)
    subset_shifted.columns = ["P1_day_0", "P1_week_0", "P1_month_0"]
    original_ = pd.concat([original, subset_shifted], axis = 1)
    print(original_)

结果,我有3个额外的列,其值来自之前的0行。

   P1_day  P1_week  P1_month  P1_day_0  P1_week_0  P1_month_0
0      50       17        55       NaN        NaN         NaN
1      45        3        10       NaN        NaN         NaN
2      93       79        84       NaN        NaN         NaN
3      99       38        33      50.0       17.0        55.0
4      44       35        35      45.0        3.0        10.0
5      25       43        87      93.0       79.0        84.0
6      38       88        56      99.0       38.0        33.0
7      20       66         6      44.0       35.0        35.0
8       4       23         6      25.0       43.0        87.0
9      39       75         3      38.0       88.0        56.0

在接下来的迭代中,我做了 shift(2) 用同样的方法,并收到了来自的栏目。original.iloc[1].在最后一次迭代中,我做了 shift(1) 并得到了预期的结果,鉴于。

 result = original_.iloc[3:]

   P1_day  P1_week  P1_month  P1_day_0  P1_week_0  P1_month_0  P1_day_1  P1_week_1  P1_month_1  P1_day_2  P1_week_2  P1_month_2
3      99       38        33      50.0       17.0        55.0      45.0        3.0        10.0      93.0       79.0        84.0
4      44       35        35      45.0        3.0        10.0      93.0       79.0        84.0      99.0       38.0        33.0
5      25       43        87      93.0       79.0        84.0      99.0       38.0        33.0      44.0       35.0        35.0
6      38       88        56      99.0       38.0        33.0      44.0       35.0        35.0      25.0       43.0        87.0
7      20       66         6      44.0       35.0        35.0      25.0       43.0        87.0      38.0       88.0        56.0
8       4       23         6      25.0       43.0        87.0      38.0       88.0        56.0      20.0       66.0         6.0
9      39       75         3      38.0       88.0        56.0      20.0       66.0         6.0       4.0       23.0         6.0

问题: 有没有什么方法可以解决这个任务 用我描述的更好的方法?谢谢,我有一个这样的数据框: original = pd.DataFrame(np.random.randand)。

python pandas dataframe transpose shift
1个回答
1
投票

除非你想要所有这些额外的DataFrames,否则你可以直接将新的列添加到你的原始df中。

import pandas as pd
import numpy as np

original = pd.DataFrame(
    np.random.randint(0,100,size=(10, 3)), 
    columns=["P1_day", "P1_week", "P1_month"],
)

original[
    ["P1_day_0", "P1_week_0", "P1_month_0"]
] = original[
    ["P1_day", "P1_week", "P1_month"]
].shift(3)

print(original)

输出:

   P1_day  P1_week  P1_month  P1_day_0  P1_week_0  P1_month_0
0       2       35        26       NaN        NaN         NaN
1      99        4        96       NaN        NaN         NaN
2       4       67         6       NaN        NaN         NaN
3      76       33        31       2.0       35.0        26.0
4      84       60        98      99.0        4.0        96.0
5      57        1        58       4.0       67.0         6.0
6      35       70        96      76.0       33.0        31.0
7      81       32        39      84.0       60.0        98.0
8      25        4        38      57.0        1.0        58.0
9      83        4        60      35.0       70.0        96.0

python教程链接到示例

编辑:OP问了后续问题。

是的,对于第一行来说,这是有意义的,但是,我的任务是将索引0-1-2的前3行添加为新的9列,从第3个索引开始。但是,我的任务是将索引0-1-2的前3行作为新的9列添加到从第3个索引开始的行中。在你的输出中,索引为1的行没有作为3列添加到第3行中。在我的代码中,这就是为什么我反复使用shift(2)和shift(1)的原因。

下面是如何迭代完成的。

import pandas as pd
import numpy as np

original = pd.DataFrame(
    np.random.randint(0,100,size=(10, 3)), 
    columns=["P1_day", "P1_week", "P1_month"],
)

for shift, n in ((3,0),(2,1),(1,2)):
    original[
        [f"P1_day_{n}", f"P1_week_{n}", f"P1_month_{n}"]
    ] = original[
        ["P1_day", "P1_week", "P1_month"]
    ].shift(shift)

pd.set_option('display.max_columns', None)
print(original.iloc[3:])

输出:

   P1_day  P1_week  P1_month  P1_day_0  P1_week_0  P1_month_0  P1_day_1  \
3      58       43        74      26.0       56.0        82.0      56.0   
4      44       27        40      56.0       87.0        38.0      31.0   
5       2       90         4      31.0       32.0        87.0      58.0   
6      90       70         6      58.0       43.0        74.0      44.0   
7       1       31        57      44.0       27.0        40.0       2.0   
8      96       22        69       2.0       90.0         4.0      90.0   
9      13       98        47      90.0       70.0         6.0       1.0   

   P1_week_1  P1_month_1  P1_day_2  P1_week_2  P1_month_2  
3       87.0        38.0      31.0       32.0        87.0  
4       32.0        87.0      58.0       43.0        74.0  
5       43.0        74.0      44.0       27.0        40.0  
6       27.0        40.0       2.0       90.0         4.0  
7       90.0         4.0      90.0       70.0         6.0  
8       70.0         6.0       1.0       31.0        57.0  
9       31.0        57.0      96.0       22.0        69.0

python教程链接

编辑2:这里不做任何假设,但如果你的最终目标是从所有这些新列的数据中获得类似4期移动平均线的东西,那么你可能根本不需要它们。您可以使用 pandas.DataFrame.rolling 而不是。

import pandas as pd
import numpy as np

original = pd.DataFrame(
    np.random.randint(0,100,size=(10, 3)), 
    columns=["P1_day", "P1_week", "P1_month"],
)

original[
    ["P1_day_4PMA", "P1_week_4PMA", "P1_month_4PMA"]
] = original[
    ["P1_day", "P1_week", "P1_month"]
].rolling(4).mean()

pd.set_option('display.max_columns', None)
print(original.iloc[3:])

输出。

   P1_day  P1_week  P1_month  P1_day_4PMA  P1_week_4PMA  P1_month_4PMA
3       1       13        48        31.25         38.00          55.00
4      10        4        40        22.00         21.00          45.75
5       7       76         0         5.50         23.75          37.00
6       5       69         9         5.75         40.50          24.25
7      63       31        82        21.25         45.00          32.75
8      26       67        22        25.25         60.75          28.25
9      89       41        40        45.75         52.00          38.25

另一个python教程链接

© www.soinside.com 2019 - 2024. All rights reserved.