Python基于前面的3行,通过滚动窗口向DataFame添加列
我有这样一个数据帧:Python基于前面的3行,通过滚动窗口向DataFame添加列,python,pandas,dataframe,transpose,shift,Python,Pandas,Dataframe,Transpose,Shift,我有这样一个数据帧: 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
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
dataframe的第3行开始生成新的dataframe,并根据滚动窗口添加新的9列,滚动窗口定义为前3行,并带有相应的前缀:[u 0,[u 1,[u 2]。因此,它是来自original
dataframe的索引为[0,1,2]的行。
例如,接下来的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
问题:
有没有办法像我描述的那样用更好的方法来解决这个问题?谢谢。除非您需要所有这些额外的数据帧,否则您可以直接将新列添加到原始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
编辑:OP提出了后续问题:
是的,对于第一排来说是有意义的。但是,我的任务是添加索引为0-1-2的前3行,作为从第3个索引开始的相关行的新9列。在输出中,索引为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
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
编辑2:此处不做任何假设,但如果您的最终目标是从所有这些新列的数据中获得类似于4期移动平均数的数据,那么您可能根本不需要它们。您可以改为使用:
输出:
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
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
看起来您正在使用jupyter。为什么不打印(一些数据框)并复制/粘贴文本?它们看起来比图片好多了。@QuangHoang,是的,我用的是
Jupyter
。谢谢你的建议。将来我会的。是的,对于第一排来说是有意义的。但是,我的任务是添加索引为0-1-2的前3行,作为从第3个索引开始的相关行的新9列。在输出中,索引为1的行不会作为3列添加到第3行。在我的代码中,这就是我反复使用shift(2)
和shift(1)
的原因。@Cindy我在一个示例中编辑了如何对所有9个新列执行此操作。谢谢我所需要的。你对for
循环的想法看起来比我在for
循环中对[3,2,1]中的shift\u i的版本要好:subset\u shift=original[columns].shift(shift\u i)subset\u shift.columns=[s+str(shift\u i)for s in columns]。原始=pd.concat([原始,子集移位],轴=1)@Cindy Yupp!元组解包和f字符串是您的朋友。学习如何使用它们将为您节省大量代码;)@辛迪,我对我的答案做了另一次编辑,你可能想看看。看起来您正在设置为这些列查找移动平均值或其他滚动聚合值,如果是这种情况,那么您可能需要签出。