Заменить выбросы медианой, кроме NaN - PullRequest
0 голосов
/ 16 января 2020

Я хотел бы заменить выбросы медианой в кадре данных, но только выбросы, а не NaN.

Первый:

      January  February 
0      -5.0     -7.0 
1      -6.0     -6.0 
2      -5.0     -5.0  
3      -3.0     -6.0 
4      -6.0     -8.0   
5     -11.0     -9.0    
6      -6.0      5.0    
7      -8.0    -11.0  
8     -11.0    -12.0  
9      -8.0     -9.0     
10     -8.0     -6.0   
11     -8.0     -5.0    
12     -8.0     -4.0   
13    -10.0      1.0    
14    -10.0      3.0   
15     -9.0     -9.0    
16     -6.0     -6.0   
17     -6.0     -6.0   
18     -4.0     -4.0  
19     -8.0      2.0    
20     -9.0      3.0      
21    -14.0      1.0 
22    -15.0     -3.0  
23    -17.0     -4.0   
24    -19.0     -6.0     
25    -60.0     -8.0   
26     -8.0     -8.0   
27     -9.0    -11.0    
28     -5.0      NaN    
29     -6.0      NaN    
30     -7.0      NaN 

Я хотел бы заменить -60, который является выбросом с медианой:

df = df[df.apply(lambda x: np.abs(x - x.mean()) / x.std() < 4).all(axis=1)]

Работает нормально, но также удаляет все строки, содержащие NaN, как этого избежать?

Вывод:

  January  February 
0      -5.0     -7.0 
1      -6.0     -6.0 
2      -5.0     -5.0  
3      -3.0     -6.0 
4      -6.0     -8.0   
5     -11.0     -9.0    
6      -6.0      5.0    
7      -8.0    -11.0  
8     -11.0    -12.0  
9      -8.0     -9.0     
10     -8.0     -6.0   
11     -8.0     -5.0    
12     -8.0     -4.0   
13    -10.0      1.0    
14    -10.0      3.0   
15     -9.0     -9.0    
16     -6.0     -6.0   
17     -6.0     -6.0   
18     -4.0     -4.0  
19     -8.0      2.0    
20     -9.0      3.0      
21    -14.0      1.0 
22    -15.0     -3.0  
23    -17.0     -4.0   
24    -19.0     -6.0     
25    -10.0     -8.0   
26     -8.0     -8.0   
27     -9.0    -11.0

Как Вы можете видеть, 3 строки были удалены, что не очень удобно. Любые идеи ? Спасибо!

Ответы [ 2 ]

1 голос
/ 16 января 2020

Использование numpy.where(...):

df[["January", "February"]]=\
    np.where(
        df.sub(df.mean(axis=0)).abs()\
        .div(df.std(axis=0))>=4, 
        df.median(axis=0), df
    )

Вывод:

    January  February
0      -5.0      -7.0
1      -6.0      -6.0
2      -5.0      -5.0
3      -3.0      -6.0
4      -6.0      -8.0
5     -11.0      -9.0
6      -6.0       5.0
7      -8.0     -11.0
8     -11.0     -12.0
9      -8.0      -9.0
10     -8.0      -6.0
11     -8.0      -5.0
12     -8.0      -4.0
13    -10.0       1.0
14    -10.0       3.0
15     -9.0      -9.0
16     -6.0      -6.0
17     -6.0      -6.0
18     -4.0      -4.0
19     -8.0       2.0
20     -9.0       3.0
21    -14.0       1.0
22    -15.0      -3.0
23    -17.0      -4.0
24    -19.0      -6.0
25     -8.0      -8.0
26     -8.0      -8.0
27     -9.0     -11.0
28     -5.0       NaN
29     -6.0       NaN
30     -7.0       NaN
1 голос
/ 16 января 2020

Вы можете использовать .isna() в своей логике c:

df = df[df.apply(lambda x: (np.abs(x - x.mean()) / x.std() < 4) | x.isna()).all(axis=1)]
print(df)

Отпечатки (отсутствует индекс уведомления 25 (-60.0):

      January  February
0        -5.0      -7.0
1        -6.0      -6.0
2        -5.0      -5.0
3        -3.0      -6.0
4        -6.0      -8.0
5       -11.0      -9.0
6        -6.0       5.0
7        -8.0     -11.0
8       -11.0     -12.0
9        -8.0      -9.0
10       -8.0      -6.0
11       -8.0      -5.0
12       -8.0      -4.0
13      -10.0       1.0
14      -10.0       3.0
15       -9.0      -9.0
16       -6.0      -6.0
17       -6.0      -6.0
18       -4.0      -4.0
19       -8.0       2.0
20       -9.0       3.0
21      -14.0       1.0
22      -15.0      -3.0
23      -17.0      -4.0
24      -19.0      -6.0
26       -8.0      -8.0
27       -9.0     -11.0
28       -5.0       NaN
29       -6.0       NaN
30       -7.0       NaN
...