[英]Pandas replacing less than n consecutive values with neighboring consecutive value
[英]Replacing more than n consecutive values in Pandas DataFrame column
假設我有以下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個,其余5個。
因此,例如,12個連續4個將被替換為10個4和2個5。
我如何用熊貓實現這一目標?
我想應用一個lambda,但我不知道如何回顧足夠的行,它必須從最后開始並向前移動,否則會破壞值的序列。 每次查找都必須查看前面的10行,看它們是否都等於4,如果是,則將當前值設置為5。
不知道如何去做!
您可以使用:
#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]})
解決方案計數consecutives 4復位如果NaN
創建人where
,然后應用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
使用limit=10
作為參數刪除所有4s,fillna返回4s,並用5s刪除剩余的NA。 我發現這種方法更明確,更能反映出你的意圖:
df[df!=4].fillna(4, limit=10).fillna(5)
如果需要,最后將df astype(int)
為帶有astype(int)
整數, astype(int)
的入侵會將數據幀轉換為浮點數。
這應該做的伎倆:
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.