Как получить количество строк до указанной c даты с некоторыми условиями - PullRequest
3 голосов
/ 19 июня 2020

У меня есть такой набор данных:

    start_date  finish_date
0   2020-06-01  2020-06-02
1   2020-06-02  2020-06-04
2   2020-06-03  NaT
3   2020-06-04  2020-06-07
4   2020-06-05  2020-06-07
5   2020-06-06  NaT
6   2020-06-07  NaT

, который можно воссоздать с помощью следующего кода:

import pandas as pd

df = pd.DataFrame({
    'start_date': ['2020-06-01', '2020-06-02', '2020-06-03', '2020-06-04', '2020-06-05', '2020-06-06', '2020-06-07'],
    'finish_date': ['2020-06-02', '2020-06-04', pd.NA, '2020-06-07', '2020-06-07', pd.NA, pd.NA],
})
df['start_date'] = df['start_date'].apply(pd.to_datetime)
df['finish_date'] = df['finish_date'].apply(pd.to_datetime)

Вопрос: : как получить количество строк, которые не имеют finish_date или еще не завершены reporting_date, следующий ожидаемый результат:

    reporting_date  not_finished
0   2020-06-01      1
1   2020-06-02      1
2   2020-06-03      2
3   2020-06-04      2
4   2020-06-05      3
5   2020-06-06      4
6   2020-06-07      3

Чтобы объяснить ожидаемый результат выше:

(когда я говорю «строка», я имею в виду строку в наборе данных, а не результат)

  • По reporting_date 2020-06-01 строка 0 началась, но не закончилась, это считается 1.
  • По reporting_date 2020-06-02 строка 0 уже завершена, а строка 1 начата, но еще не завершена, что считается 1.
  • По reporting_date 2020-06-03, строки 1 и 2 были начаты, но еще не закончены, это считается 2.
  • По reporting_date 2020-06-04 строка 2 имеет уже завершено, а строки 2 и 3 были начаты, но еще не закончены, это считается 2.
  • и так далее ..

Ответы [ 2 ]

1 голос
/ 19 июня 2020

Используйте понимание списка для сравнения каждого reporting_date с предыдущими значениями finish_date. Чтобы обработать NaT, вам нужно fillna по pd.Timestamp.max

s = df.finish_date.fillna(pd.Timestamp.max)
df['not_finished'] = [(x < s.loc[:i]).sum()  for i, x in enumerate(df.start_date)]

Out[35]:
  start_date finish_date  not_finished
0 2020-06-01  2020-06-02             1
1 2020-06-02  2020-06-04             1
2 2020-06-03         NaT             2
3 2020-06-04  2020-06-07             2
4 2020-06-05  2020-06-07             3
5 2020-06-06         NaT             4
6 2020-06-07         NaT             3
1 голос
/ 19 июня 2020
def fn():
    d, open_dates = (yield), []
    while True:
        open_dates = [od for od in open_dates + [d.finish_date] if od is pd.NaT or od > d.start_date]
        d = yield len(open_dates)

f = fn();next(f)
df['not_finished'] = df.apply(lambda x: f.send(x), axis=1)
print(df)

Печать:

  start_date finish_date  not_finished
0 2020-06-01  2020-06-02             1
1 2020-06-02  2020-06-04             1
2 2020-06-03         NaT             2
3 2020-06-04  2020-06-07             2
4 2020-06-05  2020-06-07             3
5 2020-06-06         NaT             4
6 2020-06-07         NaT             3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...