Сохранить массив numpy в MySQL (перезагружен) - PullRequest
0 голосов
/ 09 июля 2020

Это будет дубликат массива store numpy в mysql. Причина в том, что на актуальный вопрос там нет ответа, и 5 лет спустя я (другой случайный человек) борюсь с той же проблемой.

Цель

У меня есть много numpy векторов. Я хочу сохранить каждый из них в столбце BLOB в базе данных MySQL. Я уже читал, что это, скорее всего, не очень хорошая идея , но я все равно хотел бы это сделать. Для этого я пытаюсь создать запрос. Код выглядит примерно так:

query = 'INSERT INTO vectors_table (word_id, vector) VALUES '

for i in vectors:
    query += ({}, {}).format(i.index, i.vector.dumps())

(обратите внимание на вызов .dumps())

Альтернативы

Numpy массивы имеют несколько вариантов функций для «сериализации "его данные:

Я также мог бы использовать Pickle. Есть функция под названием pickle.dumps, которая также дает мне последовательность bytes.

Проблема

Когда я пытаюсь создать запрос, он вставляет этот чертов b перед строкой. Например, если я напечатаю один из своих векторов, он будет выглядеть так:

b'\x80\x02cnumpy.core.multiarray\n_reconstruct\nq\x00cnumpy\nndarray\nq\x01K\x00\x85q\x02c_codecs\nencode\nq\x03X\x01\x00\x00\x00bq\x04X\x06\x00\x00\x00latin1q\x05\x86q\x06Rq\x07\x87q\x08Rq\t(K\x01M\x00\x0c\x85q\ncnumpy\ndtype\nq\x0bX\x02\x00\x00\x00f4q\x0cK\x00K\x01\x87q\rRq\x0e(K\x03X\x01\x00\ ...

К сожалению, как можно увидеть в разделе «Альтернативы» выше, это верно для всех альтернатив, которые я нашел до сих пор.

Попытки решения

Пытаясь решить проблему, я нахожу множество людей, говорящих мне использовать decode или преобразовывать байты в строку .

Вызов .decode('ascii') или .decode('utf-8') привел к UnicodeDecodeError: 'ascii' codec can't decode byte 0x80 in position 0: ordinal not in range(128) и UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 0: invalid start byte, соответственно.

Попытка преобразовать bytes в строку создает строку, которая включает "b".

Есть ли лучший способ сделать это?

Я новичок с MySQL и полностью верю, что мне не хватает некоторых очевидных решение. Я подхожу к тому моменту, когда я планирую просто создать строку с

for i in vectors:
    old_str = str(i.vector.dumps())
    new_str = old_str[1:]
    query += ({}, {}).format(i.index, new_str)

и просто вставить ее в свою строку запроса. Все же ... Не могу поверить, что это единственный способ заставить это работать.

1 Ответ

0 голосов
/ 24 июля 2020

В конце концов, ответ на мой вопрос был в другом вопросе . Я отвечу здесь на тот случай, если у кого-то возникнет аналогичная проблема.

Я делал

query = 'INSERT INTO vectors_table (word_id, vector) VALUES '

for i in vectors:
    query += "({}, {})".format(i.index, i.vector.dumps())

, а затем запускал cursor.execute(query).

Вместо этого я Я должен был написать свой запрос с помощью %s:

query = 'INSERT INTO vectors_table (word_id, vector) VALUES (%s, %s)'

, а затем получить все элементы, которые я хочу вставить в таблицу:

tuples = [(i.index, i.vector.dumps()) for i in vectors]

и позволить библиотеке MySQL обрабатывать экранирование плохих байтов:

cursor.executemany(query, tuples)
...