Python вставить массив NumPy в базу данных sqlite3 с помощью панд - PullRequest
0 голосов
/ 28 мая 2018

Можно ли использовать pandas для вставки и чтения пустых массивов в полях базы данных sqlite?

Я работаю с фреймами данных pandas и использую встроенные функции pandas, такие как pandas.to_sql ().Это прекрасно работает с текстом и числами, но я хотел бы сохранить массив numpy в каждом поле.

Я попытался сделать это, используя метод, описанный в вопросе «Вставка массива Python в базу данных sqlite3» https://stackoverflow.com/a/18622264/5321138. Это очень хорошо объясняет, как хранить массивы в sqlite с помощью sqlite3.Однако я бы хотел продолжать пользоваться пандами.Я попробовал самый простой подход, какой только мог себе представить:

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, по-видимому, не воспринимаются пандами, поскольку тип v1 - это "байты", а не "тупой".array "

Есть ли элегантный способ продолжать использовать панд с базой данных sqlite и иметь массивы в полях?Или я должен сделать несколько специальных методов для преобразования моих кадров данных pandas, содержащих массивы numpy, в sqlite и наоборот, используя модуль sqlite3?

1 Ответ

0 голосов
/ 28 мая 2018

Я думаю, вам нужно передать параметр sqlite3.PARSE_DECLTYPES (см. этот комментарий ):

conn = sqlite3.connect('sqlite_file.sqlite', detect_types=sqlite3.PARSE_DECLTYPES)

Вы также можете применить преобразование после загрузки кадра данных:

out['v1'] = out['v1'].apply(convert_array)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...