假设我有以下DataFrame df
df = pd.DataFrame({"a" : [1,2,2,2,2,2,2,2,2,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5], "b" : [3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,7,7], "c" : [4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,1,2,2,2,2,2,2,2,2,3,3]})
我希望替换连续重复10次以上任意列(可能有数百列)的4号,其中包括10 4和4,其余5'秒。
例如,12个连续的4个将被10个4和2个替换。
我如何通过熊猫实现这一目标?
我想申请一个lambda,但我不知道如何回顾足够的行,它必须从最后开始并向前移动,否则它会打破值。每次查找都必须查看前面的10行以查看它们是否都等于4,如果是,则将当前值设置为5.
不知道如何去做!
答案 0 :(得分:4)
您可以使用:
#column a is changed for 2 groups of 4
df = pd.DataFrame({
"a" : [4,4,4,4,4,4,4,4,4,4,4,4,4,4,7,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5],
"b" : [3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,7,7],
"c" : [4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,1,2,2,2,2,2,2,2,2,3,3]})
如果where
创建了NaN
,则解决方案会重置连续4次,然后将boolean mask
应用于原始df
以将4
替换为5
mask
:
a = df == 4
mask = a.cumsum()-a.cumsum().where(~a).ffill().fillna(0) > 10
df1 = df.mask(mask, 5)
print (df1)
a b c
0 4 3 4
1 4 3 4
2 4 3 4
3 4 3 4
4 4 3 4
5 4 3 4
6 4 3 4
7 4 4 4
8 4 4 4
9 4 4 4
10 5 4 5
11 5 5 5
12 5 5 5
13 5 5 5
14 7 5 5
15 4 5 5
16 4 5 5
17 4 5 5
18 4 5 5
19 4 5 5
20 4 5 5
21 4 5 1
22 4 5 2
23 4 5 2
24 4 5 2
25 5 5 2
26 5 5 2
27 5 5 2
28 5 6 2
29 5 6 2
30 5 7 3
31 5 7 3
为了更好地检查值,可以使用concat
:
print (pd.concat([df, df1], axis=1, keys=['orig','new']))
orig new
a b c a b c
0 4 3 4 4 3 4
1 4 3 4 4 3 4
2 4 3 4 4 3 4
3 4 3 4 4 3 4
4 4 3 4 4 3 4
5 4 3 4 4 3 4
6 4 3 4 4 3 4
7 4 4 4 4 4 4
8 4 4 4 4 4 4
9 4 4 4 4 4 4
10 4 4 4 5 4 5
11 4 5 4 5 5 5
12 4 5 4 5 5 5
13 4 5 4 5 5 5
14 7 5 4 7 5 5
15 4 5 4 4 5 5
16 4 5 4 4 5 5
17 4 5 4 4 5 5
18 4 5 5 4 5 5
19 4 5 5 4 5 5
20 4 5 5 4 5 5
21 4 5 1 4 5 1
22 4 5 2 4 5 2
23 4 5 2 4 5 2
24 4 5 2 4 5 2
25 4 5 2 5 5 2
26 4 5 2 5 5 2
27 4 5 2 5 5 2
28 4 6 2 5 6 2
29 5 6 2 5 6 2
30 5 7 3 5 7 3
31 5 7 3 5 7 3
答案 1 :(得分:2)
使用limit=10
作为参数,以4s删除所有4s,fillna,并用5s删除剩余的NA。我发现这种方法更明确,更能反映出你的意图:
df[df!=4].fillna(4, limit=10).fillna(5)
如果需要,最后将df强制转换为astype(int)
的整数,因为NAs的入侵会将数据帧转换为浮点数。
答案 2 :(得分:1)
这应该可以解决问题:
import pandas as pd
df = pd.DataFrame({"a" : [1,2,2,2,2,2,2,2,2,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5], "b" : [3,3,3,3,3,3,3,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,7,7], "c" : [4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,1,2,2,2,2,2,2,2,2,3,3]})
def replacer(l,target_val=4,replace_val=5,repeat_max=10):
counter = 0
new_l = []
for e in l:
if e == target_val: counter += 1
else:
counter = 0
if counter > repeat_max:
new_l.append(replace_val)
else:
new_l.append(e)
return new_l
df1 = df.apply(replacer)
输出:
a b c
0 1 3 4
1 2 3 4
2 2 3 4
3 2 3 4
4 2 3 4
5 2 3 4
6 2 3 4
7 2 4 4
8 2 4 4
9 3 4 4
10 3 4 5
11 4 5 5
12 4 5 5
13 4 5 5
14 4 5 5
15 4 5 5
16 4 5 5
17 4 5 5
18 4 5 5
19 4 5 5
20 4 5 5
21 5 5 1
22 5 5 2
23 5 5 2
24 5 5 2
25 5 5 2
26 5 5 2
27 5 5 2
28 5 6 2
29 5 6 2
30 5 7 3
31 5 7 3