根据列向量制作Pandas掩码

yln*_*nor 1 python mask filter slice pandas

我有一个给定的数据帧,我希望每一行能够选择高于该行给定百分位数的值.

让我们考虑一下这个数据帧:

df = pd.DataFrame({'A' : [5,6,3,4, 0,5,9], 'B' : [1,2,3, 5,7,0,1]})

   A  B
0  5  1
1  6  2
2  3  3
3  4  5
4  0  7
5  5  0
6  9  1
Run Code Online (Sandbox Code Playgroud)

并且每行的第20个分位数的给定向量:

rowsQuantiles = df.quantile(0.2, axis=1)

0    1.8
1    2.8
2    3.0
3    4.2
4    1.4
5    1.0
6    2.6
Run Code Online (Sandbox Code Playgroud)

我希望能够为每行过滤出行的分位数以下的值,以获得以下结果:

quantileMask = df > rowsQuantiles

   A      B
0  True   False
1  True   False
2  False  False
3  False  True  
4  False  True  
5  True   False
6  True   False
Run Code Online (Sandbox Code Playgroud)

编辑:

我真的很喜欢@andrew_reece和@Andy Hayden的两种方法,所以我决定看哪一个是紧固/最好的实现:

N=10000000
df = pd.DataFrame({'A' : [random.random() for i in range(N)], 'B' : [random.random() for i in range(N)]})
rowsQuantiles = df.quantile(0.2, axis=1)

t0=time.time()

mask=(df.T>rowsQuantiles).T
#mask=df.apply(lambda row: row > rowsQuantiles)

print(str(time.time()-t0))
Run Code Online (Sandbox Code Playgroud)

结果非常简单(经过多次重复测试):

  • 220ms内mask=(df.T>rowsQuantiles).T
  • 为65μsmask=df.apply(lambda row: row > rowsQuantiles)
  • 21msdf.gt(rowsQuantiles,0),公认的答案.

WeN*_*Ben 5

也只使用 gt

df.gt(rowsQuantiles,0)
Out[288]: 
       A      B
0   True  False
1   True  False
2  False  False
3  False   True
4  False   True
5   True  False
6   True  False
Run Code Online (Sandbox Code Playgroud)

运用 add

df.add(-rowsQuantiles,0).gt(0)
Out[284]: 
       A      B
0   True  False
1   True  False
2  False  False
3  False   True
4  False   True
5   True  False
6   True  False
Run Code Online (Sandbox Code Playgroud)