将列表写入CSV文件

时间:2016-05-28 12:22:56

标签: c# csv

我有一个名为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列表都是神经网络中最后一层和下一层之间的权重)。

2 个答案:

答案 0 :(得分:7)

以下是如何做到这一点:

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();

答案 1 :(得分:3)

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

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

如果您真的不关心为处理器(或加速器)进行超级优化,我会选择一个简单的嵌套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元素的性能测试(不计算写入文件):

enter image description here

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

如果您想进一步优化,请考虑总有空间:)

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

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