Расчет с несколькими датами в одной ячейке в кадре данных - PullRequest
0 голосов
/ 13 апреля 2020

Предположим, у меня есть фрейм данных, такой как ниже

   userid   recorddate              alertdate
0    tom    2018-06-12 00:00:00.0   2018-06-13 00:00:00.0, 2015-04-13 00:00:00.0
1    nick   2019-06-01 00:00:00.0   2019-11-11 00:00:00.0, 2020-02-12 00:00:00.0, 2020-01-10 00:00:00.0
2    bob    2019-06-02 00:00:00.0   2019-06-01 00:00:00.0

Что я хочу сделать, так это взять даты в столбце "alerttdate" и посмотреть, есть ли какие-либо из них в течение 10 дней до начала записи.

В этом примере Том будет из-за значения 2018-06-13.

Я знаю, как это сделать, если в alerttdate есть только одна дата, но в этом столбце может быть много дат, разделенных столбцом.

Любая помощь или советы для этого? Я хотел бы создать новый столбец с простым логическим значением о наличии оповещения в течение 10 дней после записи. Если это возможно, без создания новых строк для разделения дат, потому что кадр данных будет содержать столбцы других данных и хотел бы предотвратить дублирование.

Спасибо!

Ответы [ 2 ]

0 голосов
/ 13 апреля 2020

Подход:

  1. Я прочитал в вашем входе с разделителем-пробелом.
  2. Я преобразовал строки в списки в столбце df['alertdate'] с помощью split().
  3. Я создал столбец с именем df['alertdate_lt_10days'], который сначала предполагает «Нет», а затем возвращает «Да» для соответствующих строк.
  4. Я прокрутил столбцы, строки и ячейки с ключевыми вещами: a. первый оператор for - используйте от zip() до l oop через строки двух столбцов одновременно и b. второе for утверждение - l oop через списки в ячейках столбца alerttdate, чтобы иметь возможность сравнивать даты, чтобы увидеть, если они были в течение 10 дней друг от друга
  5. Я преобразовал дату записи и изменить применительно к датам, а затем использовал .days для преобразования объекта timedelta в integer (вычитание дат по умолчанию создает объект timedelta, который нельзя сравнить с целыми числами).
  6. Наконец, я использовал очень полезный и практичный np.where() для присвоения «Да» новому столбцу, который мы создали ранее.

Код:

import pandas as pd
import numpy as np
df=pd.read_clipboard(sep='\s+\s+')

df['alertdate'] = df['alertdate'].apply(lambda x: x.split(','))
df['alertdate_lt_10days'] = 'No'
for recorddate, list_alertdate in zip(df['recorddate'], df['alertdate']):
    for alertdate in list_alertdate:
        if -10 < (pd.to_datetime(alertdate) - pd.to_datetime(recorddate)).days < 10:
            df['alertdate_lt_10days'] = np.where(df['recorddate'] == recorddate, 'Yes', df['alertdate_lt_10days'])
df

Выход:

        userid  recorddate                  alertdate             alertdate_lt_10days
0       tom     2018-06-12 00:00:00.0       [2018-06-13 00:00:00.0, 2015-04-13 00:00:00.0]  Yes
1       nick    2019-06-01 00:00:00.0       [2019-11-11 00:00:00.0, 2020-02-12 00:00:00.0...    No
2       bob     2019-06-02 00:00:00.0       [2019-06-01 00:00:00.0]            Yes
0 голосов
/ 13 апреля 2020

Вы можете превратить значения 'alerttdate' в списки дат с помощью str.split():

df['alertdate'] = df['alertdate'].str.split(', ')

Затем вы можете просто l oop над строками и элементами списка для каждой строки, чтобы сделать сравнения, используя pd.to_datetime().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...