【问题标题】:How to convert numpy array to postgresql list如何将numpy数组转换为postgresql列表
【发布时间】:2014-06-26 18:37:27
【问题描述】:

我正在尝试使用 python 将 numpy 数组的 2 列作为两个数组插入到 postgresql 表中。

postgresql 表是 DOS: 首要的关键 能量整数[] dos 整数[]

我有一个 numpy 数组,它是 2x1D 数组的二维数组:

finArray = np.array([energy,dos])

我正在尝试使用以下脚本插入数据库,但插入时不断出现错误。我不知道如何格式化数组,使其正确格式化为:INSERT INTO dos VALUES(1,'{1,2,3}','{1,2,3}')"

脚本:

import psycopg2
import argparse
import sys
import re
import numpy as np
import os

con = None


try:    
    con = psycopg2.connect(database='bla', user='bla')
    cur = con.cursor()
    cur.execute("INSERT INTO dos VALUES(1,'{%s}')", [str(finArray[0:3,0].tolist())[1:-1]])
    con.commit()


except psycopg2.DatabaseError, e:
    if con:
        con.rollback()

    print 'Error %s' % e
    sys.exit(1)

finally:
    if con:
        con.close()

我想不通的部分是我会收到这样的错误:

Error syntax error at or near "0.31691105000000003"
LINE 1: INSERT INTO dos VALUES(1,'{'0.31691105000000003, -300.0, -19...

我无法弄清楚括号中那个内部“ ”是从哪里来的。

【问题讨论】:

标签: python arrays postgresql numpy


【解决方案1】:

为时已晚,但还是把它放出来。

我今天试图在 Redshift 中插入一个 numpy 数组。在尝试了ododf.to_sql() 等等之后,我终于让它以相当快的速度(~3k 行/分钟)工作。我不会谈论我在使用这些工具时遇到的问题,但这里有一些简单有效的方法:

cursor = conn.cursor()

args_str = b','.join(cursor.mogrify("(%s,%s,...)", x) for x in tuple(map(tuple,np_data)))

cursor.execute("insert into table (a,b,...) VALUES "+args_str.decode("utf-8"))
cursor.commit()
cursor.close()

根据数组的尺寸,第二行需要做一些工作。

您可能也想检查这些答案:

  1. Converting from numpy array to tuple
  2. Multiple row inserts in psycopg2

【讨论】:

    【解决方案2】:

    您可能有一个字符串数组,尝试更改您的命令添加astype(float),例如:

    cur.execute("INSERT INTO dos VALUES(1,'{%s}')", [str(finArray[0:3,0].astype(float).tolist())[1:-1]])
    

    【讨论】:

      【解决方案3】:

      引号出现在numpy.ndarray.tolist() 期间,因为您实际上有字符串。如果您不想像@Saullo Castro 建议的那样假设数据是float-typed,您也可以做一个简单的str(finArray[0:3,0].tolist()).replace("'","")[1:-1] 来摆脱它们。

      但是,更合适的是,如果您在脚本中以任何方式处理 finArray 中的数据并假设它们是数字,您可能应该确保将它们作为数字导入到数组中。 您可以要求数组具有特定的数据类型,同时通过指定来启动它,例如finArray = np.array(..., dtype=np.float),然后向后工作到适合强制执行类型的位置。

      【讨论】:

      • 感谢您的帮助,但我仍然遇到类似的错误。我能找到的唯一对我有用的解决方案是创建一个这样的字符串: cur.execute(str("INSERT INTO dos VALUES(1,'{%s}','{%s}',%s, 0)" % (str(atomNumbers)[1:-1],str(orbitalNum)[1:-1],finArray[0,0]))) 在 psycopg2 中有一些警告,我应该避免使用 % string插值即使我的头上有枪,所以我不确定我是否做了坏事。 [链接]initd.org/psycopg/docs/usage.html
      【解决方案4】:

      Psycopg 会将 Python 列表调整为数组,因此您只需将 numpy 数组转换为 Python 列表并将其传递给执行方法

      import psycopg2
      import numpy as np
      
      energy = [1, 2, 3]
      dos = [1, 2, 3]
      finArray = np.array([energy,dos])
      insert = """
          insert into dos (pk, energy) values (1, %s);
      ;"""
      conn = psycopg2.connect("host=localhost4 port=5432 dbname=cpn")
      cursor = conn.cursor()
      cursor.execute(insert, (list(finArray[0:3,0]),))
      conn.commit()
      conn.close()
      

      【讨论】:

        【解决方案5】:

        您需要将numpy数组转换为列表,例如:

        import numpy as np
        import psycopg2
        fecha=12
        tipo=1
        precau=np.array([20.35,25.34,25.36978])
        conn = psycopg2.connect("dbname='DataBase' user='Administrador' host='localhost' password='pass'")
        cur = conn.cursor()
        #make a list
        vec1=[]
        for k in precau:
            vec1.append(k)
        #make a query
        query=cur.mogrify("""UPDATE prediccioncaudal SET fecha=%s, precaudal=%s WHERE idprecau=%s;""", (fecha,vec1,tipo))
        #execute a query
        cur.execute(query)
        #save changes
        conn.commit()
        #close connection
        cur.close()
        conn.close()
        

        【讨论】:

          猜你喜欢
          • 2021-06-09
          • 2020-09-18
          • 2017-03-08
          • 2015-02-15
          • 2019-08-30
          • 2015-01-07
          • 2022-10-15
          • 1970-01-01
          相关资源
          最近更新 更多