python ProgrammingError:(psycopg2.ProgrammingError)无法适应类型'numpy.ndarray'

mbyulnm0  于 5个月前  发布在  Python
关注(0)|答案(5)|浏览(55)

我正在使用pandas创建一个python脚本来读取一个具有多个行值的文件。
读取后,我需要构建一个包含这些值的数组,然后将其赋给一个行值。
我使用的代码是

import re
import numpy as np
import pandas as pd
master_data = pd.DataFrame()
temp_df = pd.DataFrame()
new_df = pd.DataFrame()

for f in data:

##Reading the file in pandas which is in excel format 
#
file_df = pd.read_excel(f)

filename = file_df['Unnamed: 1'][2]

##Skipping first 24 rows to get the required reading values
column_names = ['start_time','xxx_value']
data_df = pd.read_excel(f, names=column_names, skiprows=25)

array =np.array([])

   for i in data_df.iterrows():
       array = np.append(array,i[1][1])

   temp_df['xxx_value'] = [array]
   temp_df['Filename'] = filename
   temp_df['sub_id']=       
   temp_df['Filename'].str.split('_',1).str[1].str.strip() 
   temp_df['sen_site']=    
   temp_df['Filename'].str.split('_',1).str[0].str.strip()
   temp_df['sampling_interval'] = 15
   temp_df['start_time'] = data_df['start_time'][2]

   new_df= new_df.append(xxx_df)

   new_df.index = new_df.index + 1
   new_df=new_df.sort_index()
   new_df.index.name='record_id'

  new_df = new_df.drop("Filename",1)    ##dropping the Filename as it          
  is not needed to be loaded in postgresql

 ##Rearrange to postgresql format
 column_new_df = new_df.columns.tolist()
 column_new_df.
 insert(4,column_new_df.pop(column_new_df.index('xxx_value')))
 new_df = new_df.reindex(columns = column_new_df)

 print(new_df)

字符串
当我尝试将数组数据插入到Postgresql中时,这段代码不起作用。
它给了我一个错误,说明:
ProgrammingError:(psycopg2.ProgrammingError)无法适应类型'numpy.ndarray'

3mpgtkmj

3mpgtkmj1#

在我看来,最有效的方法是让psycopg 2总是知道np.ndarray(s)。可以通过注册一个适配器来做到这一点:

import numpy as np
from psycopg2.extensions import register_adapter, AsIs

def addapt_numpy_array(numpy_array):
    return AsIs(tuple(numpy_array))

register_adapter(np.ndarray, addapt_numpy_array)

字符串
为了帮助使用numpy,我对依赖于psycopg 2的脚本/库的默认插件是:

import numpy as np
from psycopg2.extensions import register_adapter, AsIs

def addapt_numpy_float64(numpy_float64):
    return AsIs(numpy_float64)

def addapt_numpy_int64(numpy_int64):
    return AsIs(numpy_int64)

def addapt_numpy_float32(numpy_float32):
    return AsIs(numpy_float32)

def addapt_numpy_int32(numpy_int32):
    return AsIs(numpy_int32)

def addapt_numpy_array(numpy_array):
    return AsIs(tuple(numpy_array))

register_adapter(np.float64, addapt_numpy_float64)
register_adapter(np.int64, addapt_numpy_int64)
register_adapter(np.float32, addapt_numpy_float32)
register_adapter(np.int32, addapt_numpy_int32)
register_adapter(np.ndarray, addapt_numpy_array)


否则即使是数字类型也会有一些问题。
我从这个其他stackoverflow entry得到了适配器技巧。

vohkndzv

vohkndzv2#

我不知道问题出在哪里,因为我在你的代码中看不到你将数据插入Postgres的部分。
我的猜测是你给了Postgres一个Numpy数组:psycopg2不能处理Numpy数据类型,但它应该很容易将其转换为与psycopg2一起工作的原生Python类型(例如,通过使用.tolist(方法),如果没有代码,很难给予更精确的信息)。

2admgd59

2admgd593#

首先使用applytolist将每个numpy数组元素转换为其等效列表,然后您应该能够将数据写入Postgres:

df['column_name'] = df['column_name'].apply(lambda x: x.tolist())

字符串

093gszye

093gszye4#

我们可以通过一次提取一个元素来解决这个问题。这里我假设对于numpy.int64类型的temp_dfsub_id,我们可以直接使用iloc和item作为temp_df.iloc[0]['sub_id'].item()提取值,然后我们可以将其推送到DB中。

xhv8bpkk

xhv8bpkk5#

from pgvector.psycopg2 import register_vector
db_connection = psycopg2.connect(dsn)

register_vector(db_connection)

字符串
您需要导入register_vector,以便它可以与numpy数组一起工作。如果您正在使用PostgreSQL的PG Vector插件,则也需要这样做。

相关问题