Как оптимизировать итерацию по совокупным дням и местоположению? - PullRequest
1 голос
/ 17 июня 2020

У меня есть фрейм данных, который состоит из событий с их датой, 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.

При необходимости могу предоставить более подробную информацию.

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