2014-08-27 68 views
1

我想用列中值替換列中值以上的所有值。改進代碼以取代中位數值大於中值的大熊貓DataFrame

這裏是我的數據框:

m = pd.DataFrame({ 
    'a': xrange(5), 
    'b': xrange(5, 10), 
    'c': xrange(10,15)}) 

print m 

    a b c 
0 0 5 10 
1 1 6 11 
2 2 7 12 
3 3 8 13 
4 4 9 14 

這裏是我的解決方案:

for col in m.columns: 
    quart = m[col].median() 
    m[col] = [val if val < quart else quart for val in m[col]] 

print m 

    a b c 
0 0 5 10 
1 1 6 11 
2 2 7 12 
3 2 7 12 
4 2 7 12 

我不熟悉的數據幀,所以我在想,如果有可能做到這一點更'熊貓「的方式或使用一些花式的線性代數。

非常感謝您的回覆。


編輯答案:

下面是分別從hurrial和chrisb的解決方案的快速timeit:

%timeit m.apply(lambda col: np.where(col.median() < col, col.median(), col)) 
1000 loops, best of 3: 1.36 ms per loop 

%timeit np.minimum(m, m.median()) 
1000 loops, best of 3: 400 µs per loop 

使用np.minimum的解決方案似乎更快。

謝謝我今天學到了2個強大的東西,np.where和np.minimum!

回答

0

有幾種不同的方式來做到這一點。一般來說,使用列表理解不是表達熊貓操作的有效方式 - 該特定行可以被重寫爲(參見indexing docs)。

m.loc[m[col] >= val, col] = quart 

但整個操作可以寫在一行,像這樣(進口numpy as np):

In [211]: m = np.minimum(m, m.median()) 

In [212]: m 
Out[212]: 
    a b c 
0 0 5 10 
1 1 6 11 
2 2 7 12 
3 2 7 12 
4 2 7 12 
0

您可以使用numpy whereapply做在一個數據幀中的所有列:

import numpy as np 
    import pandas as pd 

    m = pd.DataFrame({ 
     'a': range(5), 
     'b': range(5, 10), 
     'c': range(10,15)}) 

    print(m) 
     a b c 
    0 0 5 10 
    1 1 6 11 
    2 2 7 12 
    3 3 8 13 
    4 4 9 14 

    m.apply(lambda col: np.where(col.median()>col, col.median(), col)) 

    print(m) 

     a b c 
    0 2 7 12 
    1 2 7 12 
    2 2 7 12 
    3 3 8 13 
    4 4 9 14