【问题标题】:Saving a Pandas DataFrame to a Django Model将 Pandas DataFrame 保存到 Django 模型
【发布时间】:2016-06-07 19:46:49
【问题描述】:

我有存储在 pandas DataFrame 中的股票价格数据,如下所示(实际上它在面板中,但我将其转换为 DataFrame)

        date  ticker  close       tsr
0 2013-03-28  abc     22.81  1.000439
1 2013-03-28  def     94.21  1.006947
2 2013-03-28  ghi     95.84  1.014180
3 2013-03-28  jkl     31.80  1.000000
4 2013-03-28  mno     32.10  1.003125
...many more rows

我想将其保存在 Django 模型中,如下所示(与列名匹配):

class HistoricalPrices(models.Model):
    ticker = models.CharField(max_length=10)
    date = models.DateField()
    tsr = models.DecimalField()
    close = models.DecimalField()

到目前为止,我想到的最好的方法是使用它来保存它,其中 df 是我的 DataFrame:

entries = []
for e in df.T.to_dict().values():
    entries.append(HistoricalPrices(**e))
HistoricalPrices.objects.bulk_create(entries)

有没有更好的保存方法?

我查看了django-pandas,但看起来它只是从数据库中读取的。

【问题讨论】:

    标签: python django pandas


    【解决方案1】:

    to_sql()engine 的适当connection 参数一起使用是最有效的,并在您的Django 应用程序中运行此程序,而不是遍历DataFrame 并将一个model 实例保存在一次:

    from django.conf import settings
    
    user = settings.DATABASES['default']['USER']
    password = settings.DATABASES['default']['PASSWORD']
    database_name = settings.DATABASES['default']['NAME']
    
    database_url = 'postgresql://{user}:{password}@localhost:5432/{database_name}'.format(
        user=user,
        password=password,
        database_name=database_name,
    )
    
    engine = create_engine(database_url, echo=False)
    df.to_sql(HistoricalPrices, con=engine)
    

    【讨论】:

    • 有什么方法可以将数据库生成的自动 ID 恢复到DataFrame 中? (我的 Excel 数据需要存储在几个外键链接的 Django 模型中。)
    • 您始终可以使用read_sql 来获取包含所有自动生成列的完整 df。 django 本身只会使用数据库生成的id,如果这就是你所指的。
    • 感谢@Stefan,在我的情况下,识别我最新的行子集将是一项昂贵的操作,并且可能容易出错。也就是说seems 的替代方法是锁定表并手动设置 ID,或者写入via CSV,因此也可能会影响性能或丢失 ID,也许这只是批量插入的基本限制。我会做更多的研究并报告。
    • 反响很好。只是想知道您将从 Django 框架中将此代码放入哪个文件中?
    • 两个问题 -- (1) 有没有办法从设置中加载 database_url 而不是硬编码? (2) 这是最矢量化的方式吗?
    【解决方案2】:

    更简单的方法,你可以试试这个:

    json_list = json.loads(json.dumps(list(df.T.to_dict().values())))
    
    for dic in json_list:
         HistoricalPrices.objects.get_or_create(**dic)
    

    【讨论】:

    • 一次插入一行绝不是一个好的选择。更少的代码行并不重要。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-21
    • 2018-01-04
    • 1970-01-01
    • 1970-01-01
    • 2020-08-02
    • 1970-01-01
    相关资源
    最近更新 更多