有一个像这样的数据框:
import numpy as np
import pandas as pd
df = pd.DataFrame({'x':np.arange(1,29),'y':[5.69, 6.03, 6.03, 6.03, 6.03, 6.03, 6.03, 5.38, 5.21, 5.4 , 5.24,
5.4 , 5.36, 5.47, 5.58, 5.5 , 5.61, 5.53, 5.4 , 5.51, 5.47, 5.44,5.39, 5.27, 5.38, 5.35, 5.32, 5.09],
'valley':[1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
'peak':[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0]})
>>> df
x y valley peak
0 1 5.69 1 0
1 2 6.03 0 0
2 3 6.03 0 1
3 4 6.03 0 0
4 5 6.03 0 0
5 6 6.03 0 0
6 7 6.03 0 0
7 8 5.38 0 0
8 9 5.21 1 0
9 10 5.40 0 0
10 11 5.24 0 0
11 12 5.40 0 0
12 13 5.36 0 0
13 14 5.47 0 0
14 15 5.58 0 0
15 16 5.50 0 0
16 17 5.61 0 1
17 18 5.53 0 0
18 19 5.40 0 0
19 20 5.51 0 0
20 21 5.47 0 0
21 22 5.44 0 0
22 23 5.39 0 0
23 24 5.27 0 0
24 25 5.38 0 0
25 26 5.35 0 0
26 27 5.32 0 0
27 28 5.09 1 0
我希望向该数据框添加一个新列“grp”,要求对于谷值列以“1”开头、峰值列以“1”结尾的每一行,添加的列中的值为“A”,反之,对于峰值列以“1”开头、谷值列以“1”结尾的每一行,添加的列中的值为“B”。
期望的结果是:
>>> out
x y valley peak grp
0 1 5.69 1 0 A
1 2 6.03 0 0 A
2 3 6.03 0 1 B
3 4 6.03 0 0 B
4 5 6.03 0 0 B
5 6 6.03 0 0 B
6 7 6.03 0 0 B
7 8 5.38 0 0 B
8 9 5.21 1 0 A
9 10 5.40 0 0 A
10 11 5.24 0 0 A
11 12 5.40 0 0 A
12 13 5.36 0 0 A
13 14 5.47 0 0 A
14 15 5.58 0 0 A
15 16 5.50 0 0 A
16 17 5.61 0 1 B
17 18 5.53 0 0 B
18 19 5.40 0 0 B
19 20 5.51 0 0 B
20 21 5.47 0 0 B
21 22 5.44 0 0 B
22 23 5.39 0 0 B
23 24 5.27 0 0 B
24 25 5.38 0 0 B
25 26 5.35 0 0 B
26 27 5.32 0 0 B
27 28 5.09 1 0 A
如果我们不使用带有函数和 for 循环的 apply,是否有一种使用 pandas 的原生方法来实现?
根据您的描述,您可以使用
np.select
和ffill
。这样,您可以确保即使在山谷之前有多个山峰,或者相反,这将保持顺序:变体为
case_when
:或者
from_dummies
在添加新列后:或者重塑:
或者,如果总是有一个谷值,然后是峰值,然后是谷值......您可以使用
cumsum
+mod
和map
之后的组来识别哪一个峰值/谷值是第一个:输出: