Хранение 2D массива с C # и чтение с Python и наоборот - PullRequest
0 голосов
/ 04 июня 2019

У меня есть частичное решение ниже; то есть я понял, как читать и декодировать байтовый массив обратно в 2D-массив.

Я сохраняю большой двумерный двойной массив в виде varbinary в SQL. Я делаю это с помощью Buffer.BlockCopy для создания (линейного) байтового массива из двумерного двойного массива.

У меня для этого определен следующий класс:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TestCSSQL
{
    class clsMatrixVarbinary
    {
        Random random = new Random();

        public byte[] DoubleMatrixToByteArray(double[,] doubleArray)
        {
            int rows = doubleArray.GetLength(0);
            int cols = doubleArray.GetLength(1);

            byte[] byteArray = new byte[rows * cols * sizeof(double)];
            Buffer.BlockCopy(doubleArray, 0, byteArray, 0, byteArray.Length);

            return byteArray;
        }

        public double[,] VarBinaryToDoubleMatrix (byte[] byteArray, int rows, int cols)
        {
            double[,] doubleArray = new double[rows, cols];
            for (int r=0; r<rows; r++)
            {
                for (int c=0; c<cols; c++)
                {
                    doubleArray[r,c] = BitConverter.ToDouble(byteArray, r * cols * sizeof(double) + c * sizeof(double));
                }
            }
            return doubleArray;
        }

        public double[,] MakeRandomTestMatrix(int rows, int cols)
        {
            double[,] randomMatrix = new double[rows, cols];
            for (int r = 0; r < rows; r++)
            {
                for (int c = 0; c < cols; c++)
                {
                    randomMatrix[r, c] = random.Next(-200, 200);
                }
            }
            return randomMatrix;
        }

        // Summation of all cells in a matrix, just a quick verification check.
        // The intent is to verify that when a matrix is read from the database,
        // the reconstructed matrix has the same checksum as the one that was saved.
        //
        public double computeChecksum(double[,] dblArray)
        {
            int rank = dblArray.Rank; // rank is the number of dimensions of an array.
            int rows = dblArray.GetLength(0);
            int cols = dblArray.GetLength(1);
            double sum = 0.0;

            for (int r = 0; r < rows; r++)
            {
                for (int c = 0; c < cols; c++)
                {
                    sum += dblArray[r, c];
                }
            }

            return sum;
        }
    }
}

Затем я сохраняю некоторую информацию в базе данных SQL - байтовый массив, имя для массива, некоторые примечания, количество строк и столбцов (для восстановления массива) и контрольную сумму ... некоторые другие вещи, не относящиеся к вопрос.

У меня есть процедура тестирования, чтобы убедиться, что C # правильно читает / декодирует и записывает / кодирует.

Но некоторые вещи, которые я хочу сделать с python. У меня есть скрипт, который читает запись из таблицы хранимых матриц (байтовые массивы). Он читает всю информацию правильно (я думаю). Но у меня возникают проблемы с выяснением того, как декодировать сохраненные в varbinary данные (массив байтов в C #).

Я пытаюсь

cursor.execute("SELECT * FROM dbo.test_varbinary_table WHERE [name]= 'CIV' AND [version]= 'AAA'")
result = cursor.fetchone()

rows = result.rows
cols = result.cols
bitString = result.vb_data
Matrix = [[0 for x in range(cols)] for y in range(rows)]
for r in range(rows):
    for c in range(cols):
        #Original line
        #Matrix[r][c] = struct.unpack_from('d', bitString, (r * cols + c)*8)
        #This is the fix.  Not sure why this is necessary. Need to read docs more thoroughly.
        Matrix[r][c] = struct.unpack_from('d', bitString, (r * cols + c)*8)[0]
print(type(Matrix))
sum = 0
for r in range(rows):
    for c in range(cols):
        sum += Matrix[r][c]
print("sum  = " + str(sum))

Однако это не работает, как я ожидаю. Я должен верить, что это обычное дело. Есть ли стандартный способ сделать это? Изменить: у меня сейчас эта часть работает (или, по крайней мере, кажется). Мне все еще нужно выяснить обратное (создать в Python / сохранить в SQL / прочитать в C # / восстановить двойной массив 2D). Обратите внимание, что единственное, что нужно было получить нулевой элемент кортежа.

И вот, это правильно в документе, который я прочитал 3 раза: "struct.unpack_from (fmt, buffer, offset = 0) ... В результате получается кортеж, даже если он содержит ровно один элемент ... "

https://docs.python.org/3.1/library/struct.html#struct-alignment

...