Как я могу преобразовать строки с диапазоном дат в строки с каждой датой в ярости? - PullRequest
0 голосов
/ 19 февраля 2020

Допустим, у меня есть следующие данные, извлеченные из базы данных:

data = [ 
    {'db_id': 1, 'start': '2020-02-02', 'end': '2020-02-05'},
    {'db_id': 2, 'start': '2020-02-04', 'end': '2020-02-06'},
    {'db_id': 3, 'start': '2020-02-02', 'end': '2020-02-04'}
]
df = pd.DataFrame(data)

Я хочу преобразовать это в строку для каждой комбинации date / db_id, включая дату начала и окончания , Поэтому я хочу получить следующий DataFrame:

result_data = [
    {'db_id': 1, 'date': '2020-02-02'},
    {'db_id': 1, 'date': '2020-02-03'},
    {'db_id': 1, 'date': '2020-02-04'},
    {'db_id': 1, 'date': '2020-02-05'},
    {'db_id': 2, 'date': '2020-02-04'},
    {'db_id': 2, 'date': '2020-02-05'},
    {'db_id': 2, 'date': '2020-02-06'},
    {'db_id': 3, 'date': '2020-02-02'},
    {'db_id': 3, 'date': '2020-02-03'},
    {'db_id': 3, 'date': '2020-02-04'},
]

result_df = pd.DataFrame(result_data)

Какой эффективный способ сделать это в pandas (в наборе данных несколько сотен тысяч строк).

Ответы [ 2 ]

2 голосов
/ 19 февраля 2020

Вы можете сделать resample, но сначала вам нужно убедиться, что ваша дата имеет тип datetime:

df['start'], df['end'] = pd.to_datetime(df['start']), pd.to_datetime(df['end'])

(df.melt(id_vars='db_id', value_name='date')
   .set_index('date')
   .groupby('db_id')['variable'].resample('D').ffill()
   .reset_index()
   .drop('variable',axis=1)
)

Вывод:

   db_id       date
0      1 2020-02-02
1      1 2020-02-03
2      1 2020-02-04
3      1 2020-02-05
4      2 2020-02-04
5      2 2020-02-05
6      2 2020-02-06
7      3 2020-02-02
8      3 2020-02-03

Или вы можете также сделать простой for l oop:

pd.concat(pd.DataFrame({'db_id':x['db_id'], 
                        'date':pd.date_range(x['start'], x['end'], freq='D')}
                        ) 
          for _, x in df.iterrows()
         )
0 голосов
/ 19 февраля 2020

Создайте новый фрейм данных из genex

df_final = pd.DataFrame(((i, d) for i, s, e in zip(df.db_id, df.start, df.end) 
                                    for d in pd.date_range(s, e, freq='D')), 
                        columns=['db_id', 'date'])

Out[90]:
   db_id       date
0      1 2020-02-02
1      1 2020-02-03
2      1 2020-02-04
3      1 2020-02-05
4      2 2020-02-04
5      2 2020-02-05
6      2 2020-02-06
7      3 2020-02-02
8      3 2020-02-03
9      3 2020-02-04
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...