У меня есть Pandas фрейм данных в виде:
Time Temperature Voltage Current
0.0 7.8 14 56
0.1 7.9 12 58
0.2 7.6 15 55
... So on for a few hundred thousand rows...
Мне нужно как можно быстрее массово вставить данные в базу данных PostgreSQL. Это для проекта Django, и в настоящее время я использую ORM для операций с БД и построения запросов, но открыта для предложений, если есть более эффективные способы выполнения sh задачи.
Мои данные Модель выглядит следующим образом:
class Data(models.Model):
time = models.DateTimeField(db_index=True)
parameter = models.ForeignKey(Parameter, on_delete=models.CASCADE)
parameter_value = models.FloatField()
Итак, Time
- это row[0]
DataFrame, а затем для каждого столбца заголовка я беру значение, соответствующее ему, используя заголовок как parameter
. Таким образом, row[0]
примера таблицы сгенерирует 3 Data
объектов в моей базе данных:
Data(time=0.0, parameter="Temperature", parameter_value=7.8)
Data(time=0.0, parameter="Voltage", parameter_value=14)
Data(time=0.0, parameter="Current", parameter_value=56)
Наше приложение позволяет пользователю анализировать файлы данных, которые измеряются в миллисекундах. Таким образом, мы генерируем много отдельных объектов данных из одного файла. Моя текущая задача - улучшить синтаксический анализатор, чтобы сделать его намного более эффективным, пока мы не достигнем ограничений ввода / вывода на аппаратном уровне.
Мое текущее решение - go через каждую строку, создать один Data
Объект для каждой строки в time + parameter + value
и добавить указанный объект в массив, чтобы я мог от Data.objects.bulk_create(all_data_objects)
до Django. Конечно, я знаю, что это неэффективно и, вероятно, может быть значительно улучшено.
Используя этот код:
# Convert DataFrame to dict
df_records = df.to_dict('records')
# Start empty dta array
all_data_objects = []
# Go through each row creating objects and appending to data array
for row in df_records:
for parameter, parameter_value in row.items():
if parameter != "Time":
all_data_objects.append(Data(
time=row["Time"],
parameter_value=parameter_value,
parameter=parameter))
# Commit data to Postgres DB
Data.objects.bulk_create(all_data)
В настоящее время вся операция, без БД Включенная операция вставки (запись на диск), то есть просто создание массива объектов Data
, для файла размером 55 МБ, генерирующего около 6 миллионов отдельных Data
объектов, занимает около 370 секунд. Просто линия df_records = df.to_dict('records')
занимает 83i sh секунды. Времена были измерены с использованием time.time()
на обоих концах каждого участка и расчета разности.
Как я могу улучшить это время?