У меня есть фрейм данных, который состоит из событий с их датой, location_id и еще один с location_id и отсортированным индексом.
data = pd.DataFrame(data={'date':['2020-01-01', '2020-01-02','2020-01-01'],
'location_id':[100, 2500, 56029],
})
data
date location_id
0 2020-01-01 100
1 2020-01-02 2500
2 2020-01-01 56029
location = pd.DataFrame(data={'location_id':[100,2500,56029]}, index=[1,2,3])
location
location_id
1 100
2 2500
3 56029
Я хочу подсчитать количество событий для каждого местоположения за день и затем используйте location_id
в другом фрейме данных, чтобы в конечном итоге создать массив numpy для каждого дня, который содержит количество событий, и используйте массив для другого уравнения, которое у меня есть. Так, например, если есть 1000 местоположений, то в данном примере мне нужен массив numpy, который для 2020-01-01
я получаю массив нулей везде, кроме строк 1 и 3, которые будут равны 1 и аналогично в строке 2020-01-02
2 будет 1 и ноль везде.
Вот мой обходной путь:
NumberOfLocations = location.shape[0]
NumberOfEvents_atLocations = np.zeros((NumberOfLocations,1))
df = data
Format = '%Y-%m-%d'
start_date = datetime.datetime.strptime(min(df.date), Format)
end_date = datetime.datetime.strptime(max(df.date), Format)
daterange = pd.date_range(start_date, end_date)
for t in daterange:
date = t.date().strftime('%Y-%m-%d')
NumberOfEvents_atLocations = np.zeros((NumberOfLocations,1))
NumberOfEvents_atLocations_df = pd.DataFrame(NumberOfEvents_atLocations, location.location_id)
if not(df[df.date == date].empty):
NumberOfEvents_atLocations_index = df[df.date == date].location_id.value_counts().index
NumberOfEvents_atLocations_df.loc[NumberOfEvents_atLocations_index] = np.vstack(df[df.date == date].location_id.value_counts().values)
else:
NumberOfEvents_atLocations_index = 0
del NumberOfEvents_atLocations_index
Это отлично работает; однако этот код работает очень медленно, поскольку у меня есть данные за более чем 15 лет. Вот несколько моментов о данных, над которыми я работаю сейчас:
- В
data
кадре данных дата, location_id и индекс не сортируются; однако при необходимости их, конечно, можно отсортировать. - Могут быть дни, когда событие не было записано, поэтому в теле for-l есть выражение if-else oop.
- location_id не имеет смысла. Это просто идентификаторы.
- Индекс кадра данных
location
в порядке, поэтому я использую его для создания массива numpy. - Одно из решений для ускорения этого процесса может быть для хранения количества событий в отдельном фрейме данных по датам. Однако набор данных, с которым я работаю, содержит данные с точностью до часа, и в конечном итоге я могу разделить дни на 6-часовые / 12-часовые периоды, поэтому я хотел бы иметь такую гибкость для будущей реализации.
Я чувствую, что эту реализацию можно значительно улучшить. Я уже смотрел df.grouby().size()
; однако, похоже, может потребоваться два цикла for: один для даты и один для location_id.
При необходимости могу предоставить более подробную информацию.