我想根据列中的相对排名删除值。具体来说,我想隔离几列中的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值的原始数据框。
答案 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