我有一个数据帧,它由一些上下浮动的值组成,x
是一些循环的基础,cycle
是一个表示循环的列。
从x
的最低点开始一个循环,从x
上升到最高点,之后x
再次下降到最低点,开始一个新的循环。这表示两个循环:最低x
—>最高x
—>最低x
—>最高x
—>最低x
…重复.
一个周期x
的最高点在cycle
列中表示为1,x
的最低点在cycle
列中表示为0。参见下面的一些示例数据,注意,周期的最高点和最低点在x
的不同点,每个周期。
import pandas as pd
import numpy as np
x = [1,2,3,4,5,4,3, # cycle 1
2,3,4,5,4,3,2, # cycle 2
1,2,3,4,5,6,5, # cycle 3
4] # cycle 4
points = [0, np.nan, np.nan, np.nan, 1, np.nan, np.nan, # cycle 1
0, np.nan, np.nan, 1, np.nan, np.nan, np.nan, # cycle 2
0, np.nan, np.nan, np.nan, np.nan, 1, np.nan, # cycle 3
0] # cycle 4
df = pd.DataFrame({'x':x, 'cycle':points})
我需要创建两个新列,指示每一行是循环的一部分的高点和低点,这个循环将在每次新的循环开始时重置cycle
列中的0值。
期望的最终结果将是如下所示的df:
low = [1,1,1,1,1,1,1, # cycle 1
2,2,2,2,2,2,2, # cycle 2
1,1,1,1,1,1,1, # cycle 3
4] # cycle 4
high = [5,5,5,5,5,5,5, # cycle 1
5,5,5,5,5,5,5, # cycle 2
6,6,6,6,6,6,6, # cycle 3
4] # cycle 4
new_df = pd.DataFrame({'x':x, 'cycle':points, 'low':low, 'high':high})
注意,索引为21的循环的最后一个开始值将具有高值等于低值,因为该循环仅由一个数据点组成。
有人知道如何自动生成这些列吗?(我的实际数据集具有相同的结构,但有更多的行和更多的循环)
下面是使用Pandas填充和插值方法的一种方法:
# Add 'low' column
df.loc[df["cycle"] == 0, "low"] = df.loc[df["cycle"] == 0, "x"]
df["low"] = df["low"].fillna(method="ffill").astype(int)
# Add 'high' column
df["high"] = df["cycle"].replace(0, np.nan)
df.loc[df["high"] == 1, "high"] = df.loc[df["high"] == 1, "x"]
df.loc[~df["cycle"].isna(), "high"] = df.loc[~df["cycle"].isna(), "high"].fillna(
method="bfill"
)
df["high"] = df["high"].interpolate("pad").astype(int)
# Deal with last row
if df.loc[df.shape[0] - 1, "cycle"] == 0:
df.loc[df.shape[0] - 1, "high"] = df.loc[df.shape[0] - 1, "low"]
:
print(df)
# Output
x cycle low high
0 1 0.0 1 5
1 2 NaN 1 5
2 3 NaN 1 5
3 4 NaN 1 5
4 5 1.0 1 5
5 4 NaN 1 5
6 3 NaN 1 5
7 2 0.0 2 5
8 3 NaN 2 5
9 4 NaN 2 5
10 5 1.0 2 5
11 4 NaN 2 5
12 3 NaN 2 5
13 2 NaN 2 5
14 1 0.0 1 6
15 2 NaN 1 6
16 3 NaN 1 6
17 4 NaN 1 6
18 5 NaN 1 6
19 6 1.0 1 6
20 5 NaN 1 6
21 4 0.0 4 4