我有以下形式的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进行数据库操作和构建查询,但是如果有更有效的方法来完成任务,则可以提出建议。
我的数据模型如下:
class Data(models.Model):
time = models.DateTimeField(db_index=True)
parameter = models.ForeignKey(Parameter, on_delete=models.CASCADE)
parameter_value = models.FloatField()
因此Time
是DataFrame的row[0]
,然后对于每个标题列,我将标题用作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)
我们的应用程序允许用户解析以毫秒为单位的数据文件。因此,我们从单个文件中生成很多单独的数据对象。我当前的任务是提高解析器的效率,直到在硬件级别上达到I / O约束为止。
我当前的解决方案是遍历每一行,为Data
上的每一行创建一个time + parameter + value
对象,并将该对象附加到数组,以便我可以通过Django Data.objects.bulk_create(all_data_objects)
。我当然知道这是低效率的,可能会改善很多。
使用此代码:
# 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)
当前整个操作,无包括的DB插入操作,即仅生成Data
对象数组,对于一个55mb的文件,它生成大约600万个单独的Data
对象,大约需要370秒。仅df_records = df.to_dict('records')
行需要83秒钟。使用每个部分两端的time.time()
测量时间并计算差异。
如何改善这些时间?
您无需为所有行都创建Data对象。 SqlAlchemy还以这种方式支持批量插入: