#python #pandas #date #datetime #missing-data
#python #pandas #Дата #дата и время #отсутствует-данные
Вопрос:
мы работаем над фреймом данных pandas, который выглядит как показано ниже. Здесь столбец времени имеет приращение в 15 минут, и есть несколько отсутствующих записей времени. Мы хотим заполнить недостающие записи времени соответствующей датой и заполнить все соответствующие поля нулями. Вот как выглядит фрейм данных.
df=
date.y timeslot_1 ProductId PlantId region UserId Gender AgeGroup Weights
6/07/2018 1:15:00 1002 8577 6 Mab 2 S 1432.6
6/07/2018 1:15:00 1002 8577 6 Mac 2 M 1629.3
6/07/2018 1:15:00 1001 8647 6 Maa 2 P 5299.6
6/07/2018 1:45:00 1001 7636 C Mab 1 T 1626.4
6/07/2018 1:45:00 1002 8577 6 Maa 1 T 1476.1
6/07/2018 1:45:00 1002 8577 6 Mab 2 S 1432.6
6/07/2018 1:45:00 1002 8577 6 Mac 2 M 1629.3
6/07/2018 1:45:00 1001 8647 6 Maa 2 P 5299.6
6/07/2018 2:00:00 1001 8647 6 Maa 2 P 4731.6
6/07/2018 2:15:00 1001 7636 C Mab 1 T 1638.6
6/07/2018 2:15:00 1002 8808 C Maa 2 M 2465.3
6/07/2018 2:30:00 1002 7491 4 Mab 1 N 5419.8
6/07/2018 2:45:00 1002 7491 4 Mab 1 N 5419.8
6/07/2018 3:15:00 1001 8362 6 Maa 2 X 2227.6
6/07/2018 3:15:00 1002 8714 C Maa 2 P 1820.6
6/07/2018 3:15:00 1001 8668 5 Mab 2 S 2048.4
6/07/2018 4:00:00 1002 8714 C Maa 2 P 1820.6
Мы подумали о создании другого базового файла, который содержал бы все увеличенное на 15 минут время с соответствующей датой, а затем объединил базовый файл с исходным фреймом данных. Однако некоторые из них, похоже, не работают. Объединение просто помещает все места из базового файла в конец каждой даты. Вот как выглядит объединенный фрейм данных.
date.y timeslot_1 ProductId PlantId region UserId Gender AgeGroup Weights
6/7/2018 1:15:00 1002 8577 6 Mab 2 S 1432.6
6/7/2018 1:15:00 1002 8577 6 Mac 2 M 1629.3
6/7/2018 1:15:00 1001 8647 6 Maa 2 P 5299.6
6/7/2018 1:45:00 1001 7636 C Mab 1 T 1626.4
6/7/2018 1:45:00 1002 8577 6 Maa 1 T 1476.1
6/7/2018 1:45:00 1002 8577 6 Mab 2 S 1432.6
6/7/2018 1:45:00 1002 8577 6 Mac 2 M 1629.3
6/7/2018 1:45:00 1001 8647 6 Maa 2 P 5299.6
6/7/2018 2:00:00 1001 8647 6 Maa 2 P 4731.6
6/7/2018 2:15:00 1001 7636 C Mab 1 T 1638.6
6/7/2018 2:15:00 1002 8808 C Maa 2 M 2465.3
6/7/2018 2:30:00 1002 7491 4 Mab 1 N 5419.8
6/7/2018 2:45:00 1002 7491 4 Mab 1 N 5419.8
6/7/2018 3:15:00 1001 8362 6 Maa 2 X 2227.6
6/7/2018 3:15:00 1002 8714 C Maa 2 P 1820.6
6/7/2018 3:15:00 1001 8668 5 Mab 2 S 2048.4
6/7/2018 4:00:00 1002 8714 C Maa 2 P 1820.6
6/7/2018 1:15:00
6/7/2018 1:30:00
6/7/2018 1:45:00
6/7/2018 2:00:00
6/7/2018 2:15:00
6/7/2018 2:30:00
6/7/2018 2:45:00
6/7/2018 3:00:00
6/7/2018 3:15:00
6/7/2018 3:30:00
6/7/2018 3:45:00
Ниже приведен код
date1='06/03/2018'
date2='06/10/2018'
d=pd.date_range(start=date1 ' 02:00:00', end=date2 ' 02:00:00', freq='15min')
columns=['date']
all_spots=pd.DataFrame(columns=columns)
all_spots=all_spots.assign(date=d)
all_spots=all_spots.astype(str)
all_spots = pd.DataFrame(all_spots.date.str.split(' ',1).tolist(),columns = ['date.y','timeslot_1'])
d=pd.merge(df,all_spots,how='outer', on=['date.y','timeslot_1'])
Вот как будет выглядеть результат.
date.y timeslot_1 ProductId PlantId region UserId Gender AgeGroup Weights
6/07/2018 1:15:00 1002 8577 6 Mab 2 S 1432.6
6/07/2018 1:15:00 1002 8577 6 Mac 2 M 1629.3
6/07/2018 1:15:00 1001 8647 6 Maa 2 P 5299.6
6/07/2018 1:30:00 0 0 0 0 0 0 0
6/07/2018 1:45:00 1001 7636 C Mab 1 T 1626.4
6/07/2018 1:45:00 1002 8577 6 Maa 1 T 1476.1
6/07/2018 1:45:00 1002 8577 6 Mab 2 S 1432.6
6/07/2018 1:45:00 1002 8577 6 Mac 2 M 1629.3
6/07/2018 1:45:00 1001 8647 6 Maa 2 P 5299.6
6/07/2018 2:00:00 1001 8647 6 Maa 2 P 4731.6
6/07/2018 2:15:00 1001 7636 C Mab 1 T 1638.6
6/07/2018 2:15:00 1002 8808 C Maa 2 M 2465.3
6/07/2018 2:30:00 1002 7491 4 Mab 1 N 5419.8
6/07/2018 2:45:00 1002 7491 4 Mab 1 N 5419.8
6/07/2018 3:00:00 0 0 0 0 0 0 0
6/07/2018 3:15:00 1001 8362 6 Maa 2 X 2227.6
6/07/2018 3:15:00 1002 8714 C Maa 2 P 1820.6
6/07/2018 3:15:00 1001 8668 5 Mab 2 S 2048.4
6/07/2018 3:30:00 0 0 0 0 0 0 0
6/07/2018 3:45:00 0 0 0 0 0 0 0
6/07/2018 4:00:00 1002 8714 C Maa 2 P 1820.6
PS Следует отметить, что это всего лишь фрагмент данных. У нас есть данные за один месяц. Итак, нам нужно позаботиться о дате, а время указано в 24-часовом формате.
Мы надеялись, что кто-нибудь может помочь решить эту проблему.
Заранее большое спасибо!!
Ответ №1:
Я думаю, вам нужно создать еще один фрейм данных для объединения с вашим фреймом данных.
# Change "1:15", "4:00" to "0:00, 23:59" for your actual data.
hr_range = pd.date_range("1:15", "4:00", freq="15min").strftime('%H:%M:%S')
# Remove 0 to match your format
hr_range = hr_range.str.lstrip('0')
df2 = pd.DataFrame()
df2['timeslot_1'] = hr_range
df2['date.y'] = pd.to_datetime('2018-06-07')
Затем преобразуйте date.y
в datetime
и set_index
оба фрейма данных с ['date.y', 'timeslot_1']
помощью .
df['date.y'] = pd.to_datetime(df['date.y'])
df.set_index(['date.y', 'timeslot_1'], inplace=True)
df2.set_index(['date.y', 'timeslot_1'], inplace=True)
И join
их вместе с how='outer'
df.join(df2, how='outer').fillna(0).reset_index()
Альтернативное решение без использования .set_index
(df.merge(df2, on=['date.y', 'timeslot_1'], how='outer')
.sort_values(['date.y', 'timeslot_1'])
.fillna(0))
Комментарии:
1. Большое спасибо за ответ. Следует отметить, что
date.y
это не одна дата. Это также диапазон дат. Мы создали диапазон, используяpd.date_range(start=date1 ' 02:00:00', end=date2 ' 02:00:00', freq='15min')
. однако нам пришлось преобразовать это в строку, чтобы разделить их по датам и времени в отдельном столбце. Кроме того, дата и время в исходном фрейме данных имеют формат даты и времени. Рекомендуете ли вы преобразовывать их в строку при создании форматаhr_range
in string2. @AnalyticsTeam Вы можете использовать
pd.date_rage(start_date, end_date)
вместо одной даты. Также, прежде чем разбивать вашеdatetime
на дату и время, вы можете использовать вашеpd.date_range
, аset_index
затемjoin
их вместе. Я должен преобразовать его, чтобыstring
сделать его совместимым с вашим примером фрейма данных.