У меня есть некоторые проблемы с производительностью панд.У меня довольно большой фрейм данных, который содержит около 3000 продуктов, обозначенных unique_id
(и несколькими записями для каждого продукта).Мне нужно отфильтровать фрейм данных для каждого продукта, выполнить некоторые вычисления и обновить базовый фрейм данных.Сейчас я делаю что-то вроде этого:
for unique_id in self.df.unique_id.unique():
# prod_df = self.df[(self.df["unique_id"] == unique_id)]
prod_df = self.df.query(f"unique_id == {unique_id}")
some_function(prod_df)
И
def some_function(prod_df):
... some code ...
values = some_values
for idx, val in zip(prod_df.index, some_values):
self.df.loc[idx, "foo_column"] = val
Этот код, однако, очень медленный (я говорю здесь несколько часов ...).Я провел быстрое профилирование, и, похоже, мой сценарий тратит большую часть времени выполнения на сценарии pandas indexing.py
.Здесь не так уж много сюрпризов.
Мне было интересно, есть ли решение панд для решения этой проблемы.Я думаю, что фильтрация, а также, возможно, и запись значений по индексу, убивают качество моего сценария.Любая идея?На данный момент я думаю поместить свой фрейм данных в dict или в базу данных sqlite.
EDIT:
Вот типичная функция, которую я мог бы использовать вместо some_function
:
def comp_gradient_for_column(
self, prod_df: pd.DataFrame
) -> None:
"""
Compute the gradient for a given column and insert it in the dataframe
Arguments:
prod_df (pd.DataFrame): sub-dataframe to work on
Returns:
None:
"""
values = prod_df[column_name].values
gradients = np.gradient(values)
for idx, val in zip(prod_df.index, gradients):
self.df.loc[idx, "foo_column"] = val