【发布时间】:2020-05-17 02:34:35
【问题描述】:
我有一个 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 限制。
我当前的解决方案是遍历每一行,为time + parameter + value 上的每一行创建一个Data 对象,并将所述对象附加到一个数组中,这样我就可以通过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万个单独的@ 987654334@ 个对象大约需要 370 秒。仅df_records = df.to_dict('records') 行就需要 83 秒。使用time.time()在每个部分的两端测量时间并计算差异。
我该如何改善这些时间?
【问题讨论】:
标签: python pandas postgresql django-database