选择列值在给定范围之间的行

时间:2018-01-21 12:04:21

标签: python pandas dataframe

如何使用特定范围内的值查找和删除DataFrame中的行,例如大于“2017-03-02”且小于“2017-03-05”的日期

import pandas as pd                                     

d_index = pd.date_range('2018-01-01', '2018-01-06')     
d_values = pd.date_range('2017-03-01', '2017-03-06')    

s = pd.Series(d_values)                                 
s = s.rename('values')                                  

df = pd.DataFrame(s)                                    
df = df.set_index(d_index)                              

# remove rows with specific values in 'value' column                              

在上面的示例中,我有从最早到最晚的日期排序的d_values,因此在这种情况下,按索引切片数据框可以完成工作。但我正在寻找的解决方案,当d_values不包含有序的随机日期值时也会起作用。有没有办法在熊猫中做到这一点?

2 个答案:

答案 0 :(得分:3)

选项1
pd.Series.between似乎适合这项任务。

df[~df['values'].between('2017-03-02', '2017-03-05', inclusive=False)]

               values
2018-01-01 2017-03-01
2018-01-02 2017-03-02
2018-01-05 2017-03-05
2018-01-06 2017-03-06

详细
between标识范围内的所有项 -

m = df['values'].between('2017-03-02', '2017-03-05', inclusive=False)
m

2018-01-01    False
2018-01-02    False
2018-01-03     True
2018-01-04     True
2018-01-05    False
2018-01-06    False
Freq: D, Name: values, dtype: bool

使用遮罩过滤df -

df = df[~m]

选项2
或者,使用好的旧逻辑OR -

df[~(df['values'].gt('2017-03-02') & df['values'].lt('2017-03-05'))]

               values
2018-01-01 2017-03-01
2018-01-02 2017-03-02
2018-01-05 2017-03-05
2018-01-06 2017-03-06

请注意,这两个选项都适用于datetime对象以及字符串日期列(在这种情况下,比较是字典的)。

答案 1 :(得分:2)

首先让我们改变您的DF:

In [65]: df = df.sample(frac=1)

In [66]: df
Out[66]:
               values
2018-01-03 2017-03-03
2018-01-04 2017-03-04
2018-01-01 2017-03-01
2018-01-06 2017-03-06
2018-01-05 2017-03-05
2018-01-02 2017-03-02

您可以使用DataFrame.eval方法(thanks @ cᴏʟᴅsᴘᴇᴇᴅ for the correction!):

In [70]: df[~df.eval("'2017-03-02' < values < '2017-03-05'")]
Out[70]:
               values
2018-01-01 2017-03-01
2018-01-06 2017-03-06
2018-01-05 2017-03-05
2018-01-02 2017-03-02

DataFrame.query()

In [300]: df.query("not ('2017-03-02' < values < '2017-03-05')")
Out[300]:
               values
2018-01-01 2017-03-01
2018-01-06 2017-03-06
2018-01-05 2017-03-05
2018-01-02 2017-03-02