【问题标题】:Writing list to CSV file将列表写入 CSV 文件
【发布时间】:2016-09-26 16:56:27
【问题描述】:

我有一个名为 NN 的 int 列表列表,我想将其写入 csv 文件,如下所示:

List<List<int>> NN = new List<List<int>>();

NN 列表:

1,2,3,4,5,6
2,5,6,3,1,0
0,9,2,6,7,8

输出的 csv 文件应该是这样的:

1,2,0
2,5,9
3,6,2
4,3,6
5,1,7
6,0,8

实现这一目标的最佳方法是什么?

如果有更好的表示,您会推荐而不是嵌套列表,我会很高兴知道。

(目的是每个int列表都是神经网络中最后一层和下一层之间的权重)。

【问题讨论】:

  • 所以基本上NN是一个列数据列表,对吧?
  • 嵌套for 循环是一种简单的方法。

标签: c# csv


【解决方案1】:

你可以这样做:

List<List<int>> NN = new List <List<int>>
{
    new List<int> {1,2,3,4,5,6},
    new List<int> {2,5,6,3,1,0},
    new List<int> {0,9,2,6,7,8}
};

//Get expected number of rows
var numberOfRows = NN[0].Count; 

var rows =
    Enumerable.Range(0, numberOfRows) //For each row
    .Select(row => NN.Select(list => list[row]).ToList()) //Get row data from all columns
    .ToList();

StringBuilder sb = new StringBuilder();

foreach (var row in rows)
{
    sb.AppendLine(string.Join(",", row));
}

var result = sb.ToString();

【讨论】:

    【解决方案2】:

    您要实现的基本上是矩阵转置,然后将数据写入文件。

    转置矩阵的最有效方法是什么是一个复杂的问题,实际上取决于您的架构。

    如果您并不真正关心为您的处理器(或加速器)进行超级优化,我会选择一个简单的嵌套 for 循环,在中间内存表示中累积数据:

    string[] lines = new string[NN[0].Count]; // assume all lines have equal length
    for(int i = 0; i < NN.Count; ++i) {
      for(int j = 0; j < NN[i].Count; ++j) {
         lines[j] += NN[i][j] + ((i==NN.Count - 1) ? "" : ",");
      }
    }
    File.WriteAllLines("path.csv", lines);
    

    作为第一次优化,我不建议使用列表列表,因为访问元素会非常密集。 二维数组会做得更好。

    int[,] NN = new int[3,6] {{1, 2, 3, 4, 5, 6 }, {2, 5, 6, 3, 1, 0}, {0, 9, 2, 6, 7, 8}};
    
                string[] lines = new string[NN.GetLength(1)];
                for (int i = 0; i < NN.GetLength(0); ++i)
                {
                    for (int j = 0; j < NN.GetLength(1); ++j)
                    {
                        lines[j] += NN[i,j] + ((i == NN.GetLength(0) - 1) ? "" : ",");
                    }
                }
                File.WriteAllLines("path.csv", lines); 
    

    这是一个性能测试,针对 500x500 元素(不包括写入文件):

    为了改进这个解决方案,我首先在内存中进行转置(不向文件或字符串写入任何内容),然后执行 join(,) 并写入文件(作为单字节数组)。

    如果你想进一步优化,想想总是有空间的:)

    例如,在 x86 上,根据您拥有的指令集,您可以读取this article。在启用 CUDA 的设备上,您可以阅读 that

    无论如何,一个好的解决方案总是涉及对齐的内存、子块和接近金属的编写代码(内在或汇编)。

    【讨论】:

    • “一个好的解决方案将始终涉及对齐的内存、子块和接近金属的编写代码(内在或汇编)。” 你都不是将进入 C#,这使得这个答案的整个上半部分有点无关紧要。
    • 在C#中可以对齐内存(pinvoke virtualalloc),子阻塞只是索引的问题,Pinvoking子例程也是可以的(例如转置子块)
    猜你喜欢
    • 1970-01-01
    • 2012-12-11
    • 1970-01-01
    • 1970-01-01
    • 2014-06-30
    • 2019-09-02
    相关资源
    最近更新 更多