从日期时间范围开始的第一个可用日期前一天/月/年

时间:2017-03-29 11:42:49

标签: python python-3.x pandas datetime dataframe

我有一个日期时间实例,其中包含日期(@foreach($petani as $key => $data) <tr> <th>{{$data->id_user}}</th> <th>{{$data->nama_user}}</th> <th>{{$data->alamat}}</th> <th>{{$data->no_telp}}</th> <th>{{$data->id_lokasi}}</th> </tr> @endforeach ):

dfDates

最后一天(此处:2017-03-01 00:00 2017-03-02 00:00 2017-03-04 00:00 ... )我计算前一天/月/年/等。如下:

2017-03-04

返回def previous_day(dtToday): return dtToday - pd.DateOffset(days=1) 。但是,我的日期范围(2017-03-03)无法使用此工作日。

因此,我正在寻找一种可靠的方法来查找最接近前一天/月/年/等的日期。在这种情况下,前一天它应该返回dfDates

注意,我知道您可以执行索引2017-03-02之类的操作来获取前一天的内容。然而,在上一个月(一个月内不总是-1天)甚至前一年(一年中总是30个工作日)时,它变得复杂了。因此,是否有一种可靠的方法来获得最接近的可用日期?

更新

我也理解您可以按如下方式使用timedelta:

252

但是,这与from datetime import datetime, timedelta d = datetime.today() - timedelta(days=days_to_subtract) 有何关系?如何将其与dtToday相关联?在我的情况下dfDates并不总是dtToday。有时它是一个随机的日期。

3 个答案:

答案 0 :(得分:1)

效率不高,但您可以尝试:

# From your function
day_minus_one = previous_day(dtToday)

# Return LAST element in INDEX of DF FROM START TO DAY_MINUS_ONE
actual = df.loc[:day_minus_one].index[-1]

这基本上会返回df副本的最后一个索引最多并包括day_minus_one,如果存在任何日期。这应该给你最近的日期或日期本身。

您可以尝试:

# Returns LAST element of INDEX of df from DAY_MINUS_ONE_HUNDRED to DAY_MINUS_ONE
actual_better = df.loc[day_minus_one_hundred:day_minus_one].index[-1]

如果您的数据集非常庞大,那么只能从minus_one回顾一百天,所以您不必为了找到一个日期而返回一个巨大的数组。

答案 1 :(得分:1)

如果我理解正确,您不想实际减去1天,您希望从可用日期列表中获取上一个可用日期。如果是这样的话,那就考虑一下:

#include <iostream>
#include <vector>

int main() {
    std::vector<int> notes = {1, 2, 3, 1, 20, 5, 2, 3, 1};
    std::map<transition, int> transition_counters;
    int previous_note = -1;
    for (int note: notes) {
        if (previous_note != -1) {
            transition t{previous_note, note};
            transition_counters[t] += 1;
        }
        previous_note = note;
    }

    std::cout << "all encountered transitions:\n";
    for (const auto& entry: transition_counters) {
        std::cout << '(' << entry.first.from << " -> " << entry.first.to << "): " << entry.second << '\n';
    }

    std::cout << "transitions from 1:\n";
    const auto transitions_from_1 = transitions_from(1, transition_counters);
    for (auto it = transitions_from_1.first; it != transitions_from_1.second; ++it) {
        std::cout << '(' << it->first.from << " -> " << it->first.to << "): " << it->second << '\n';
    }

    std::cout << "counters for individual transitions:\n";
    std::cout << "(1 -> 2): " << counter_for(transition{1, 2}, transition_counters) << '\n';
    std::cout << "(2 -> 1): " << counter_for(transition{2, 1}, transition_counters) << '\n';
}

当然,这假定您的available_dates = [ 2017-03-01 00:00, 2017-03-02 00:00, 2017-03-04 00:00, ... ] def previous_day(dtToday): today_index = available_dates.index(dtToday) return available_dates[today_index-1] 已排序

编辑:

如果您希望能够减去月份和年份,那么需要更复杂的东西:

available_dates

答案 2 :(得分:0)

我解决了这个问题:

  • dtToday =参考日期
  • dtDates =日期时间序列 可用日期
  • nbOffset =我们想要的天/月/年 回去

代码:

def previous_day(dtToday, dtDates, nbOffset):
    prevx   = dtToday - pd.DateOffset(days=nbOffset)
    return test_day_in(prevx, dtDates)

def previous_month(dtToday, dtDates, nbOffset):
    prevx = dtToday - pd.DateOffset(months=nbOffset)
    return test_day_in(prevx, dtDates)

def previous_year(dtToday, dtDates, nbOffset):
    prevx = dtToday - pd.DateOffset(years=nbOffset)
    return test_day_in(prevx, dtDates)

def test_day_in(dtTest, dtDates):
    if dtTest in dtDates:
        return dtTest
    else:
        return tryNextDay(dtTest, dtDates)

def tryNextDay(dtTest, dtDates):

    # if not outside the bound
    if (dtTest < dtDates.min()):
        return dtDates.min()

    # check if next day exist
    if (dtTest + pd.DateOffset(days=1) <= dtDates.max()):
        return previous_day(dtTest + pd.DateOffset(days=2), dtDates, 1) # 2-1
    else:
        print('warning, tryNextDay triggered')
        # should not be triggered, it should take by default the dtDates.min() if far outside range
        return dtTest