是否可以使用pandas在sqlite数据库的字段中插入和读取numpy数组?
我使用pandas数据帧并使用pandas内置函数,如pandas.to_sql()。这适用于文本和数字,但我想在每个字段中存储一个numpy数组。
我尝试使用问题中描述的方法" Python将numpy数组插入sqlite3数据库" https://stackoverflow.com/a/18622264/5321138。这很好地解释了如何使用sqlite3在sqlite中存储numpy数组。我想继续使用熊猫。我尝试了我能想到的最简单的方法:
import numpy as np
import pandas as pd
import sqlite3
import io
# create 3 variables of different type
value_1 = np.linspace(1,4,6)
value_2 = 42
value_3 = 'word'
print('Types of variables:')
print(type(value_1))
print(type(value_2))
print(type(value_3))
# put them in a pandas dataframe
v_dict={'v1': [value_1], 'v2':[value_2], 'v3':[value_3]}
df=pd.DataFrame(data=v_dict)
# print the types of the dataframe
print('Types of dataframe')
print(df.dtypes)
print('Types of elements of dataframe')
print(type(df['v1'].values[0]))
print(type(df['v2'].values[0]))
print(type(df['v3'].values[0]))
# make adapter and converter for numpy array that works for sqlite
# https://stackoverflow.com/questions/18621513/python-insert-numpy-array-
into-sqlite3-database
def adapt_array(arr):
"""
http://stackoverflow.com/a/31312102/190597 (SoulNibbler)
"""
out = io.BytesIO()
np.save(out, arr)
out.seek(0)
return sqlite3.Binary(out.read())
def convert_array(text):
out = io.BytesIO(text)
out.seek(0)
return np.load(out)
# Converts np.array to TEXT when inserting
sqlite3.register_adapter(np.ndarray, adapt_array)
# Converts TEXT to np.array when selecting
sqlite3.register_converter("array", convert_array)
conn = sqlite3.connect('sqlite_file.sqlite', detect_types=sqlite3.PARSE_DECLTYPES)
df.to_sql('tablen', conn, if_exists='append', index=False)
out=pd.read_sql_query('SELECT * FROM tablen', con=conn)
print('Types of elements of dataframe from sqlite')
print(type(out['v1'].values[0]))
print(type(out['v2'].values[0]))
print(type(out['v3'].values[0]))
然而,我在sqlite3中注册的适配器和转换器显然没有被pandas接收,因为v1的类型是" bytes"而不是" numpy.array"
是否有一种优雅的方法可以继续将pandas与sqlite数据库一起使用并在字段中使用numpy数组?或者我应该使用sqlite3模块制作一些专用方法将具有numpy数组的pandas数据帧转换为sqlite,反之亦然?
答案 0 :(得分:1)
我认为您需要传递sqlite3.PARSE_DECLTYPES
选项(请参阅this comment):
conn = sqlite3.connect('sqlite_file.sqlite', detect_types=sqlite3.PARSE_DECLTYPES)
您还可以在加载数据框后应用转换:
out['v1'] = out['v1'].apply(convert_array)