запись многомерных массивов в файл csv - страница 2

 
Dmitry Fedoseev:

Наверно не то. Многомерный же да в csv. А зачем? Если бы в бинарном режиме - без проблем, но это не csv.

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

Можно для разных размерностей массива использовать разные символы разделители. Потом при загрузке уже разделять данные согласно этим символам.

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

Вот пример 

void CNeuroNet::SaveWeight(string FileName)
{
   int handle = FileOpen(FileName,FILE_WRITE|FILE_TXT);
   if(handle==INVALID_HANDLE) return;   
   int LayerCount = ArraySize(NeuroLayer);
   for (int i=0;i<LayerCount;i++)
   {
      int CountNeuron = NeuroLayer[i].GetCountNeuron();
      string str = "";
      for (int j=0;j<CountNeuron;j++)
      {
         int CountWeight = ArraySize(NeuroLayer[i].Neuron[j].Weight);
         for (int k=0;k<CountWeight;k++)
         {
             str+=(DoubleToString(NeuroLayer[i].Neuron[j].Weight[k])+"|");
         }
         str+="N";
      } 
      uint b=FileWrite(handle,str);  
      if (b==0)
      {
         Print(__FUNCTION__," ошибка записи данных");
      }   
   }
   FileClose(handle);
}

NeuroLayer[i] - слой нейросети в вашем случае это будет 1-е измерения массива 

.Neuron[j] - нейрон или второе измерения массива 

.Weight[k] - вес или третье измерение массив. 

Используются символы разделители "|" и "N"

Загрузка реализована вот так:

int CNeuroNet::LoadWeight(string FileName)
{
   
   if (!FileIsExist(FileName)) return(-1);
   int handle = FileOpen(FileName,FILE_READ|FILE_TXT);
   if(handle==INVALID_HANDLE)  return(-1);
   int CountNeuron[];
   string StrL[];
   int n = 0;
   while (!FileIsEnding(handle))
   {
      string str = FileReadString(handle);
      if (str!="")
      {
        n++;
        ArrayResize(StrL,n);
        StrL[n-1] = str;
      }
    }      
    FileClose(handle);
    int LayerCount = ArraySize(StrL);//слои
    ArrayResize(CountNeuron,LayerCount);
    string StrN[];//нейроны  N - разделитель 
    string StrW[];//веса в нейроне  | - разделитель
    for (int i=0;i<LayerCount;i++)
    {
       int res=StringSplit(StrL[i],StringGetCharacter("N",0),StrN);
       if (res>0)        
       {
          CountNeuron[i] = ArraySize(StrN)-1;

          for (int j=0;j<CountNeuron[i];j++)
          {            
            res=StringSplit(StrN[j],StringGetCharacter("|",0),StrW);
            if (res>0)
            {
               int size = ArraySize(StrW)-1;
               double DoubleW[];ArrayResize(DoubleW,size);
               for (int k=0;k<size;k++) DoubleW[k]=StringToDouble(StrW[k]);
               ArrayResize(NeuroLayer[i].Neuron[j].Weight,size);
               InitWeight(DoubleW,i,j);
            }
          }                    
       }
    }
    return(1);    
}

Получается файл примерно вот такого вида:

0.00320000|0.00320000|0.00320000|0.00690000|0.00690000|0.00690000|0.00690000|0.00690000|0.00260000|N0.00320000|0.00320000|0.00320000|0.00690000|0.00690000|0.00690000|0.00690000|0.00690000|0.00260000|N0.00320000|0.00320000|0.00320000|0.00690000|0.00690000|0.00690000|0.00690000|0.00690000|0.00260000|N0.00320000|0.00320000|0.00320000|0.00690000|0.00690000|0.00690000|0.00690000|0.00690000|0.00260000|N0.00320000|0.00320000|0.00320000|0.00690000|0.00690000|0.00690000|0.00690000|0.00690000|0.00260000|N
1.43730000|1.43730000|1.43730000|1.43730000|1.43730000|N1.43730000|1.43730000|1.43730000|1.43730000|1.43730000|N1.43730000|1.43730000|1.43730000|1.43730000|1.43730000|N
0.03500000|0.03500000|0.03500000|N
 
Evgeniy Malishevskiy:

можно сплошником! arr[i][0][3][12]  получается 36 элементов надо записать

Можно сплошняком весь массив за одно действие, но в не csv, а в бинарный файл. Функции: FileWriteArray и FileReadArray

В чем задача? Просто сохранить данные в файл, а потом загрузить их в массив? Или же еще надо будет в этот файл смотреть глазами?

 
Vitalii Ananev:

Можно для разных размерностей массива использовать разные символы разделители. Потом при загрузке уже разделять данные согласно этим символам.

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

Вот пример 

NeuroLayer[i] - слой нейросети в вашем случае это будет 1-е измерения массива 

.Neuron[j] - нейрон или второе измерения массива 

.Weight[k] - вес или третье измерение массив. 

Используются символы разделители "|" и "N"

Загрузка реализована вот так:

Получается файл примерно вот такого вида:

Вообще в природе существует JSON. Но тут непонятно, тут надо понять, как человек хочет видеть свои данные в csv (если это вообще надо).

 
Dmitry Fedoseev:

Вообще в природе существует JSON. Но тут непонятно, тут надо понять, как человек хочет видеть свои данные в csv.

Это его дело, в любом случая, он должен сам это реализовать, а не ждать когда за него это напишут. Ссылку на документацию дали, примеры дали, пиши ни здоровье.

 
Dmitry Fedoseev:

Вообще в природе существует JSON. Но тут непонятно, тут надо понять, как человек хочет видеть свои данные в csv.

В каждой строке 36 элементов, запись происходит при  OnDeinit. Работа советника происходит следующим образом:

Первый запуск- снимаю значения различных переменных при открытии сделки. Переменные записываются в 2-х, 3-х и 4-х мерные массивы, в зависимости от типа переменных. Первое измерение это номер сделки, второе это переменная, третье это количество периодов по которым проиисходит снятие значений, четвёртое это количество баров в периоде с которых и снимаются расчётные переменные. 

При втором запуске в OnInit мне надо считать из файла в такой же массив эти значения и уже произвести расчёты для статистического и математического  анализа.

Для двумерного массива я использую вот такую функцию-

void WriteArray2(double &arr[][], string name="") // записывает двухмерный массив в *.csv файл

  {

   if(name=="") name=TimeToStr(TimeLocal(),TIME_DATE|TIME_SECONDS);

   

   int handle=FileOpen(name+".csv", FILE_CSV|FILE_WRITE),

       size=ArraySize(arr)/12;

   for(int i=0; i<size; i++)

       FileWrite(handle,DoubleToStr(arr[i][0],4),DoubleToStr(arr[i][1],4),DoubleToStr(arr[i][2],4),DoubleToStr(arr[i][3],4),DoubleToStr(arr[i][4],4),

                        DoubleToStr(arr[i][5],4),DoubleToStr(arr[i][6],4),DoubleToStr(arr[i][7],4),DoubleToStr(arr[i][8],4),DoubleToStr(arr[i][9],4),DoubleToStr(arr[i][10],4),DoubleToStr(arr[i][11],4));

   FileClose(handle);

  }

Можно ли её переделать под четырёхмерный?

 
Vitalii Ananev:

Это его дело, в любом случая, он должен сам это реализовать, а не ждать когда за него это напишут. Ссылку на документацию дали, примеры дали, пиши ни здоровье.

согласен)

 
ЛаДно, всем спасибо за отклик) Если долго мучиться что нибудь да получиться)Постараюсь сам сделать) Как сделаю выложу сюда)
 
Evgeniy Malishevskiy:

В каждой строке 36 элементов, запись происходит при  OnDeinit. Работа советника происходит следующим образом:

Первый запуск- снимаю значения различных переменных при открытии сделки. Переменные записываются в 2-х, 3-х и 4-х мерные массивы, в зависимости от типа переменных. Первое измерение это номер сделки, второе это переменная, третье это количество периодов по которым проиисходит снятие значений, четвёртое это количество баров в периоде с которых и снимаются расчётные переменные. 

При втором запуске в OnInit мне надо считать из файла в такой же массив эти значения и уже произвести расчёты для статистического и математического  анализа.

Для двумерного массива я использую вот такую функцию-

void WriteArray2(double &arr[][], string name="") // записывает двухмерный массив в *.csv файл

  {

   if(name=="") name=TimeToStr(TimeLocal(),TIME_DATE|TIME_SECONDS);

   

   int handle=FileOpen(name+".csv", FILE_CSV|FILE_WRITE),

       size=ArraySize(arr)/12;

   for(int i=0; i<size; i++)

       FileWrite(handle,DoubleToStr(arr[i][0],4),DoubleToStr(arr[i][1],4),DoubleToStr(arr[i][2],4),DoubleToStr(arr[i][3],4),DoubleToStr(arr[i][4],4),

                        DoubleToStr(arr[i][5],4),DoubleToStr(arr[i][6],4),DoubleToStr(arr[i][7],4),DoubleToStr(arr[i][8],4),DoubleToStr(arr[i][9],4),DoubleToStr(arr[i][10],4),DoubleToStr(arr[i][11],4));

   FileClose(handle);

  }

Можно ли её переделать под четырёхмерный?

Может вам проще использовать структуру. И не надо огород городить с многомерностью (не люблю я многомерные массивы :) )

struct SMyArr
{
  int Nomer; 
  int Var;
  int CountPeriod;
  int BarCount;  
};

SMyArr MyArr[];

Получится одномерный массив в котором в одном измерении можно хранить разные данные. 

 
Evgeniy Malishevskiy:

Работаю в екселевских таблицах

А можете вручную записать 4х мерный массив в excell, хотя-бы такой arr[2][3][2][3]; и чтобы все поняли что это именно такой массив. Ну пусть не все, достаточно чтобы сам понял где какой элемент записан.

 
Evgeniy Malishevskiy:

В каждой строке 36 элементов, запись происходит при  OnDeinit. Работа советника происходит следующим образом:

Первый запуск- снимаю значения различных переменных при открытии сделки. Переменные записываются в 2-х, 3-х и 4-х мерные массивы, в зависимости от типа переменных. Первое измерение это номер сделки, второе это переменная, третье это количество периодов по которым проиисходит снятие значений, четвёртое это количество баров в периоде с которых и снимаются расчётные переменные. 

При втором запуске в OnInit мне надо считать из файла в такой же массив эти значения и уже произвести расчёты для статистического и математического  анализа.

Для двумерного массива я использую вот такую функцию-

void WriteArray2(double &arr[][], string name="") // записывает двухмерный массив в *.csv файл

  {

   if(name=="") name=TimeToStr(TimeLocal(),TIME_DATE|TIME_SECONDS);

   

   int handle=FileOpen(name+".csv", FILE_CSV|FILE_WRITE),

       size=ArraySize(arr)/12;

   for(int i=0; i<size; i++)

       FileWrite(handle,DoubleToStr(arr[i][0],4),DoubleToStr(arr[i][1],4),DoubleToStr(arr[i][2],4),DoubleToStr(arr[i][3],4),DoubleToStr(arr[i][4],4),

                        DoubleToStr(arr[i][5],4),DoubleToStr(arr[i][6],4),DoubleToStr(arr[i][7],4),DoubleToStr(arr[i][8],4),DoubleToStr(arr[i][9],4),DoubleToStr(arr[i][10],4),DoubleToStr(arr[i][11],4));

   FileClose(handle);

  }

Можно ли её переделать под четырёхмерный?

А смотреть в файл глазами вы собираетесь? Может и не надо csv. Записать в бинарный, если смотреть в него не надо.

Причина обращения: