当列值在另一行列值的范围内时,Pandas会选择行

时间:2018-02-13 13:03:08

标签: python pandas

我正在尝试从数据框创建子集(100k-500k行) 格式如下

d = {'time':[1,2,3,5,7,9,9.5,10], 'val':['match','match','match','not','not','match','match','match']}
df = pd.DataFrame(d)

   time    val
0   1.0  match
1   2.0  match
2   3.0  match
3   5.0    not
4   7.0    not
5   9.0  match
6   9.5  match
7  10.0  match

我想在时间所在的时间内选择包含所有行的子集 范围有限。 例如,如果range为< = 1,则选择第一行和最后三行

我想要的输出:

   time    val
0   1.0  match
1   2.0  match
2   3.0  match
5   9.0  match
6   9.5  match
7  10.0  match

3 个答案:

答案 0 :(得分:2)

在一行中它看起来像这样:

df.loc[(df['time'].diff()<=1)|(df['time'].diff(-1)>=-1)]

答案 1 :(得分:1)

我有一个解决方案,但我认为这不是最好的解决方案

dfasc=df.sort_values(['time'], ascending=1)
dfdesc=df.sort_values(['time'], ascending=0)

print (df[(dfasc['time'].diff()<=1.0) | (dfdesc['time'].diff()>=-1.0)])

   time    val
0   1.0  match
1   2.0  match
2   3.0  match
5   9.0  match
6   9.5  match
7  10.0  match

答案 2 :(得分:0)

如果你想这样做,它会被矢量化,这将有效。您可能希望使用矢量化操作,因为您的DF太大了。你可能还想把它放到一个函数来节省内存,因为我在下面做了一些变量。

import numpy as np
import pandas as pd
df = pd.DataFrame({'time':[1,2,2.5,3,9,9.5,10,11,12],'val':
['not','match','match','match','match','match','match','not','not']})
'''
df
   time    val
0   1.0    not
1   2.0  match
2   2.5  match
3   3.0  match
4   9.0  match
5   9.5  match
6  10.0  match
7  11.0    not
8  12.0    not
'''
x = df.time.values
tmp = (x[1:] - x[:-1]) < 1
fst = tmp[0]
lst = tmp[-1]
mid = np.any([tmp[1:],tmp[:-1]],axis =0)
ans = np.concatenate([[fst],mid,[lst]])
df  = df[ans]
''' Output
   time    val
1   2.0  match
2   2.5  match
3   3.0  match
4   9.0  match
5   9.5  match
6  10.0  match
'''