我想在数据框中创建一个新列“标记”。 当“数字”列中的值发生更改时,我已经将“标记”的值设置为 True。 我想在“数字”列中的值更改之前和之后的两行设置“True”上的值。
我想看:
数字 | 标记 |
---|---|
10 | 错误 |
10 | 错误 |
10 | 错误 |
10 | 错误 |
10 | 正确 |
10 | 正确 |
20 | 正确 |
20 | 正确 |
20 | 错误 |
20 | 错误 |
20 | 正确 |
20 | 正确 |
30 | 正确 |
40 | 正确 |
40 | 正确 |
40 | 错误 |
40 | 错误 |
40 | 错误 |
到目前为止发现了什么:
import pandas as pd
data = [10,10,10,10,10,10,20,20,20,20,20,20,20,30,40,40,40,40,40]
df = pd.DataFrame(data, columns=['Numbers'])
check=10
def detect_changes (row):
global check
if row['Numbers'] == check :
return False
else :
check=check+10
return True
df['mark']=df.apply (lambda row: detect_changes(row), axis=1)
您可以使用滚动最大值:
# better than the used function
df['mark'] = df['Numbers'].diff().eq(10)
N = 2 # number of rows before/after
df['mark2'] = df['mark'].rolling(2*N+1, min_periods=1, center=True).max().astype(bool)
输出:
Numbers mark mark2
0 10 False False
1 10 False False
2 10 False False
3 10 False False
4 10 False True
5 10 False True
6 20 True True
7 20 False True
8 20 False True
9 20 False False
10 20 False False
11 20 False True
12 20 False True
13 30 True True
14 40 True True
15 40 False True
16 40 False True
17 40 False False
18 40 False False
# better than the used function
df['mark'] = df['Numbers'].diff().eq(10)
# 1 before
m1 = df.loc[::-1, 'mark'].rolling(1+1, min_periods=1).max().astype(bool)
# 2 after
m2 = df['mark'].rolling(2+1, min_periods=1).max().astype(bool)
df['mark2'] = m1|m2
输出:
Numbers mark mark2
0 10 False False
1 10 False False
2 10 False False
3 10 False False
4 10 False False
5 10 False True
6 20 True True
7 20 False True
8 20 False True
9 20 False False
10 20 False False
11 20 False True
12 30 True True
13 40 True True
14 40 False True
15 40 False True
16 40 False False
17 40 False False
def function1(ss:pd.Series):
if ss.iloc[1]!=ss.iloc[2]:
df1.loc[ss.index,'mark']=True
return 0
df1.rolling(4).apply(function1)
df1.fillna(False)
Numbers mark
0 10 False
1 10 False
2 10 False
3 10 False
4 10 True
5 10 True
6 20 True
7 20 True
8 20 False
9 20 False
10 20 True
11 20 True
12 30 True
另一个,使用duckdb:
(
df1.sql.select("*,lead(Numbers,1) over(order by index) col1,lead(Numbers,2) over(order by index) col2")
.select("*,max(col1!=col2) over(order by index rows between 3 preceding and current row) mark")
.order("index")
)