Pandas数据帧到大块数据库插入的对象实例的数组效率

问题描述 投票:0回答:1

我有以下形式的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()测量时间并计算差异。

如何改善这些时间?

python pandas postgresql django-database
1个回答
0
投票

您无需为所有行都创建Data对象。 SqlAlchemy还以这种方式支持批量插入:

© www.soinside.com 2019 - 2024. All rights reserved.