Pandas - 根据列内的排名删除单元格

时间:2014-10-15 16:57:01

标签: python pandas dataframe

我想根据列中的相对排名删除值。具体来说,我想隔离几列中的X最高值和X最低值。所以,如果X = 2,我的数据框看起来像这样:

ID    Val1    Val2    Val3    
001   2       8       14      
002   10      15      8
003   3       1       20
004   11      11      7
005   14      4       19

输出应如下所示:

ID    Val1    Val2    Val3    
001   2       NaN     NaN      
002   NaN     15      8
003   3       1       20
004   11      11      7
005   14      4       19

我知道我可以创建一个子表来使用以下方法隔离高等级和低等级:

df = df.sort('Column Name')
df2 = df.head(X) # OR: df.tail(X)

我想通过以下方法清除其他列中值的这些子表:

df2['Other Column'] = np.NaN
df2['Other Column B'] = np.NaN

然后将子表合并在一起,以便在其中一个表中存在数据时替换NaN值。我试过了:

df2.update(df3) # df3 is a sub-table made the same way as df2 using a different column

仅更新了df2中已存在的行。

我试过了:

out = pd.merge(df2, df3, how='outer')

当df2和d3中出现一行时,它给了我单独的行

我试过了:

out = df2.combine_first(df3)

在某些情况下,使用找到的NaN值覆盖了数值,使其不合适。

必须有一种方法可以做到这一点:只要值不在该列中的X最高值或X最低值之间,我想要插入NaN值的原始数据框。

1 个答案:

答案 0 :(得分:3)

有趣的问题是,您可以获取每列的排序值中每列的值的索引(此处位于mask DataFrame),然后保留具有索引的值你定义了边界。

In [98]:
print df
    Val1  Val2  Val3
ID                  
1      2     8    14
2     10    15     8
3      3     1    20
4     11    11     7
5     14     4    19
In [99]:

mask = df.apply(lambda x: np.searchsorted(sorted(x),x))
print mask
    Val1  Val2  Val3
ID                  
1      0     2     2
2      2     4     1
3      1     0     4
4      3     3     0
5      4     1     3
In [100]:

print (mask<=1)|(mask>=(len(mask)-2))
     Val1   Val2   Val3
ID                     
1    True  False  False
2   False   True   True
3    True   True   True
4    True   True   True
5    True   True   True
In [101]:

print df.where((mask<=1)|(mask>=(len(mask)-2)))
    Val1  Val2  Val3
ID                  
1      2   NaN   NaN
2    NaN    15     8
3      3     1    20
4     11    11     7
5     14     4    19