替换列中连续相同值后的值
Replace value after continuous same value in column
我有这样一个数据框:
df = pd.DataFrame({'A': [1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1]})
如果我有n个连续的(在这种情况下n = 8),下一个连续的n个之间的差距是4个零(我想设置一个规则例如:连续数字之间的差距是m <= 4 ), 如何用 1 替换这 4 个零?
我理想的输出是这样的:
df = pd.DataFrame({'A': [1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1], 'Fill_Gap': [1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0,0, 0, 0, 0, 0, 0, 1, 1]})
只有四个零(在索引 13-16 处)被 1 替换,因为它们前后有 8 个连续的 1。
如有任何建议,我们将不胜感激!
如果将列连接成字符串,则可以使用 regex。使用正则表达式,您可以使用 0{,4}
搜索 4 个或更少的零,然后使用 (?<=1{8})...(?=1{8})
向前看 8 个零。我认为这不是一个有效的解决方案。
import re
df['fill_gap'] = df['A']
for i in re.finditer('(?<=1{8})0{,4}(?=1{8})', ''.join(df.fill_gap.astype('str'))):
df.fill_gap.iloc[slice(*i.span())] = 1
df
输出
A fill_gap
0 1 1
1 1 1
2 1 1
3 0 0
4 0 0
5 1 1
6 1 1
7 1 1
8 1 1
9 1 1
10 1 1
11 1 1
12 1 1
13 0 1
14 0 1
15 0 1
16 0 1
17 1 1
18 1 1
19 1 1
20 1 1
21 1 1
22 1 1
23 1 1
24 1 1
25 0 0
26 1 1
27 1 1
28 1 1
29 0 0
30 0 0
31 0 0
32 0 0
33 0 0
34 0 0
35 0 0
36 0 0
37 0 0
38 1 1
39 1 1
这适用于任何长度的系列:
df = pd.DataFrame({'A': [1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1]})
#Check for runs of 8 (1's)
lst1=(df.shift(periods=0).A==1)
for x in range(1,8):
lst1=lst1&(df.shift(periods=x).A==1)
#Check for runs of 4 (0's)
lst0=(df.shift(periods=0).A==0)
for x in range(1,4):
lst0=lst0&(df.shift(periods=x).A==0)
#Get index
ones=np.array(list(lst1.index))[lst1]
zeros=np.array(list(lst0.index))[lst0]
#Fill Gaps
for x in list(range(1, len(ones))):
if any(lst0[ones[x-1]:ones[x]]):
lst1[ones[x-1]:ones[x]]=True
#Apply to data frame
df.loc[lst1, 'A']=1
输出:
A
0 1
1 1
2 1
3 0
4 0
5 1
6 1
7 1
8 1
9 1
10 1
11 1
12 1
13 1
14 1
15 1
16 1
17 1
18 1
19 1
20 1
21 1
22 1
23 1
24 1
25 0
26 1
27 1
28 1
29 0
30 0
31 0
32 0
33 0
34 0
35 0
36 0
37 0
38 1
39 1
我有这样一个数据框:
df = pd.DataFrame({'A': [1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1]})
如果我有n个连续的(在这种情况下n = 8),下一个连续的n个之间的差距是4个零(我想设置一个规则例如:连续数字之间的差距是m <= 4 ), 如何用 1 替换这 4 个零?
我理想的输出是这样的:
df = pd.DataFrame({'A': [1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1], 'Fill_Gap': [1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0,0, 0, 0, 0, 0, 0, 1, 1]})
只有四个零(在索引 13-16 处)被 1 替换,因为它们前后有 8 个连续的 1。
如有任何建议,我们将不胜感激!
如果将列连接成字符串,则可以使用 regex。使用正则表达式,您可以使用 0{,4}
搜索 4 个或更少的零,然后使用 (?<=1{8})...(?=1{8})
向前看 8 个零。我认为这不是一个有效的解决方案。
import re
df['fill_gap'] = df['A']
for i in re.finditer('(?<=1{8})0{,4}(?=1{8})', ''.join(df.fill_gap.astype('str'))):
df.fill_gap.iloc[slice(*i.span())] = 1
df
输出
A fill_gap
0 1 1
1 1 1
2 1 1
3 0 0
4 0 0
5 1 1
6 1 1
7 1 1
8 1 1
9 1 1
10 1 1
11 1 1
12 1 1
13 0 1
14 0 1
15 0 1
16 0 1
17 1 1
18 1 1
19 1 1
20 1 1
21 1 1
22 1 1
23 1 1
24 1 1
25 0 0
26 1 1
27 1 1
28 1 1
29 0 0
30 0 0
31 0 0
32 0 0
33 0 0
34 0 0
35 0 0
36 0 0
37 0 0
38 1 1
39 1 1
这适用于任何长度的系列:
df = pd.DataFrame({'A': [1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1]})
#Check for runs of 8 (1's)
lst1=(df.shift(periods=0).A==1)
for x in range(1,8):
lst1=lst1&(df.shift(periods=x).A==1)
#Check for runs of 4 (0's)
lst0=(df.shift(periods=0).A==0)
for x in range(1,4):
lst0=lst0&(df.shift(periods=x).A==0)
#Get index
ones=np.array(list(lst1.index))[lst1]
zeros=np.array(list(lst0.index))[lst0]
#Fill Gaps
for x in list(range(1, len(ones))):
if any(lst0[ones[x-1]:ones[x]]):
lst1[ones[x-1]:ones[x]]=True
#Apply to data frame
df.loc[lst1, 'A']=1
输出:
A
0 1
1 1
2 1
3 0
4 0
5 1
6 1
7 1
8 1
9 1
10 1
11 1
12 1
13 1
14 1
15 1
16 1
17 1
18 1
19 1
20 1
21 1
22 1
23 1
24 1
25 0
26 1
27 1
28 1
29 0
30 0
31 0
32 0
33 0
34 0
35 0
36 0
37 0
38 1
39 1