【问题标题】:Drop dates based on condition in python根据python中的条件删除日期
【发布时间】:2020-09-03 19:54:48
【问题描述】:

我正在尝试实现一个条件,如果不正确值的计数大于 2(在下面的示例中为 2019-05-17 和 2019-05-20),那么完整日期(所有时间块)为删除

输入

                    t_value C/IC
2019-05-17 00:00:00   0     incorrect
2019-05-17 01:00:00   0     incorrect 
2019-05-17 02:00:00   0     incorrect 
2019-05-17 03:00:00   4     correct
2019-05-17 04:00:00   5     correct 
2019-05-18 01:00:00   0     incorrect   
2019-05-18 02:00:00   6     correct  
2019-05-18 03:00:00   7     correct 
2019-05-19 04:00:00   0     incorrect
2019-05-19 09:00:00   0    incorrect 
2019-05-19 11:00:00   8    correct
2019-05-20 07:00:00   2    correct
2019-05-20 08:00:00   0    incorrect
2019-05-20 09:00:00   0    incorrect
2019-05-20 07:00:00   0    incorrect 

期望的输出

                    t_value C/IC 
2019-05-18 01:00:00   0     incorrect   
2019-05-18 02:00:00   6     correct  
2019-05-18 03:00:00   7     correct 
2019-05-19 04:00:00   0     incorrect
2019-05-19 09:00:00   0    incorrect 
2019-05-19 11:00:00   8    correct

我不确定要执行哪个基于时间的操作才能获得所需的结果。谢谢

【问题讨论】:

  • 似乎您只需要日期时间在2019-05-17 04:00:002019-05-19 11:00:00 之间的记录。 Pandas.Timestamp() 允许您通过简单的 >、
  • 是的,在这个例子中。但总的来说,我关心的是删除不正确值的相应计数大于 2 的日期。

标签: python dataframe time time-series conditional-statements


【解决方案1】:
#read in data
df = pd.read_csv(StringIO(data),sep='\s{2,}', engine='python')

#give index a name 
df.index.name = 'Date'
#convert to datetime 
#and sort index
#usually safer to sort datetime index in Pandas
df.index = pd.to_datetime(df.index)
df = df.sort_index()

res = (df
       #group by date and c/ic
       .groupby([pd.Grouper(freq='1D',level='Date'),"C/IC"])
       .size()
       #get rows greater than 2 and incorrect
       .loc[lambda x: x>2,"incorrect"]
       #keep only the date index
       .droplevel(-1)
       .index
       #datetime information trapped here
       #and due to grouping, it is different from initial datetime
       #as such, we convert to string 
       #and build another batch of dates
       .astype(str)
       .tolist()
      )

res
['2019-05-17', '2019-05-20']

#build a numpy array of dates
idx = np.array(res, dtype='datetime64')

#exclude dates in idx and get final value
#aim is to get dates, irrespective of time

df.loc[~np.isin(df.index.date,idx)]

                     t_value    C/IC
Date        
2019-05-18 01:00:00     0   incorrect
2019-05-18 02:00:00     6   correct
2019-05-18 03:00:00     7   correct
2019-05-19 04:00:00     0   incorrect
2019-05-19 09:00:00     0   incorrect
2019-05-19 11:00:00     8   correct

【讨论】:

    【解决方案2】:

    误解了问题,抱歉。

    更新答案:您可以通过以下方式找到要删除的日期:

    df['_date'] = df.index.dt.date
    incorrect_df = df[df['C/IC'] == 'incorrect']
    incorrect_count = incorrect_df['C/IC'].groupby(by='_date').count()
    dates_to_remove = set(incorrect_count[incorrect_count > 2]['_date'])
        # using set to make the later step more efficient if the df is long
    

    然后相应地屏蔽数据框:

    mask = [x not in dates_to_remove for x in df['_date']
    res = df[mask]
    

    【讨论】:

    • 感谢您的回复。我认为这不会删除所有时间块的日期。
    • 是的,很抱歉我错过了。您可以先使用df.index.dt.date 仅获取日期并将其保存到单独的列中。答案现已更新。
    猜你喜欢
    • 1970-01-01
    • 2014-09-22
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    • 2015-04-22
    • 1970-01-01
    • 2016-02-22
    • 1970-01-01
    相关资源
    最近更新 更多