#python #pandas #performance #numpy
#python #панды #Производительность #numpy
Вопрос:
У меня есть csv-файл, который выглядит следующим образом:
id date feature1 feature2 feature3
A1 01-01-2019 1 2 3
A2 01-01-2019 3 4 5
A1 01-02-2019 6 7 8
(Я составил эти цифры)
Я хотел бы сформировать 3D-массив, где одна ось — идентификатор, другая ось — дата, другие функции. В приведенном выше примере это будет выглядеть так
1 2 3
3 4 5
для дня 1,
6 7 8
nan nan nan
на 2-й день.
Итак, у меня был бы массив 2x2x3 (2 идентификатора, 2 дня, 3 функции).
Мои реальные данные имеют 800000 метров, 365 дней и 6 функций. У меня также есть словарь, dict_id
, который связывает идентификатор с индексом.
Моя реализация выглядит следующим образом:
data = pd.read_csv('data.csv')
data['date'] = pd.to_datetime(data['date'])
data['date'] = data['date'].dt.dayofyear
a,b = data.shape
output = np.full((800000,365,6),np.nan)
for i in range(a):
output[dict_id[data.iloc[i,0]],data.iloc[i,1],:] = data.iloc[i,2::]
Проблема моего подхода в том, что он очень медленный. Какие другие способы сделать это быстрее? может быть, использовать другой объект? есть ли функция, которая позволяет делать то, что я хочу, без цикла for?
Комментарии:
1. Как только у вас появляется цикл Python, вы теряете все возможности Pandas или numpy. Можно ли использовать объект или функцию numpy вместо поиска в
dict_id
?2. Почему бы просто не придерживаться pandas и не сделать что-то вроде
reindex
и использовать aMultiIndex
, чтобы получить тот же тип организации, что и с массивом numpy3. @SergeBallesta как это будет выглядеть? Словарь просто связывает идентификатор счетчика, который представляет собой строку с индексом. Индекс может быть любым, что означает: идентификатор
A1
может иметь индекс 0 или 1. @ALollz как это будет выглядеть? Я использовал цикл for, потому что я действительно не знаю, как использовать другие параметры.
Ответ №1:
Одна вещь, которую вы можете сделать, это обратиться dict_id
к ряду и отпустить for
цикл:
s = pd.Series(dict_id)
output[s[data.iloc[:,0]] , data.iloc[:,1], :] = data.iloc[:, 2::]
Комментарии:
1. конечно! Я попробую и посмотрю, насколько это быстрее.
2. Да, это намного быстрее!