【问题标题】:var [][] array remove specific wordsvar [][] 数组删除特定单词
【发布时间】:2017-09-22 00:28:05
【问题描述】:

我遇到了一个小问题。我有一个带有“NaN”值和双精度值的 .csv(例如 0.6034),我试图将 CSV 的双精度值读入数组 [y] [x]。

目前,我阅读了整个 .csv,但之后我无法删除所有“NaN”值。 (它应该通过 CSV 解析,只需将数字添加到数组 [y] [x] 并保留所有“NaN”)

我当前的代码:

 var rows = File.ReadAllLines(filepath).Select(l => l.Split(';').ToArray()).ToArray(); //reads WHOLE .CSV to array[][]


        int max_Rows = 0, j, rank;
        int max_Col = 0;
        foreach (Array anArray in rows)
        {
            rank = anArray.Rank;
            if (rank > 1)
            {
                 // show the lengths of each dimension
                for (j = 0; j < rank; j++)
                {

                }
            }
            else
            {

            }
            // show the total length of the entire array or all dimensions

            max_Col = anArray.Length; //displays columns
            max_Rows++;  //displays rows
        }

我尝试了搜索,但找不到任何对我有帮助的东西。 我知道这可能很容易,但我是 C# 新手。

.CSV 和期望的结果:

NaN;NaN;NaN;NaN
NaN;1;5;NaN
NaN;2;6;NaN
NaN;3;7;NaN
NaN;4;8;NaN
NaN;NaN;NaN;NaN

这是我拥有的示例 .csv。我应该更清楚,对不起!每行都有一个 NaN。我希望它像这样显示:

1;5
2;6
3;7
4;8

这只是 .csv 的一个示例,真正的 csv 大约有 60.000 个值...我需要使用 [y][x] 获取输入,例如 [0][0] 应该显示“1”和 [ 2][1] 应该显示“7”等等。

再次感谢您的帮助!

【问题讨论】:

  • 顺便说一句,我永远不会敢于制作自己的 CSV 解析器。解决许多极端情况 (e.g.),IMO。
  • @Uwe Keim:我同意你的观点,一般情况 CSV 看起来很复杂;但是,当 CSV 源 已知 时(例如,我自己的例程从 RDMBS 导出数据以供将来分析)或在一次性软件的情况下(我想要的只是删除不完整的行并执行线性回归在提供的 CSV 上)我会更加放纵。

标签: c# arrays csv remove-if


【解决方案1】:

您可以对数组中的分隔值进行过滤。

我稍微修改了你的代码。

 File.ReadAllLines(filepath).Select(l => l.Split(';').ToArray().Where(y => y != "NaN").ToArray()).ToArray();

【讨论】:

  • 这看起来不错,但是当我使用它并尝试通过显示 1. Value of the array -> MessageBox.Show(Convert.ToString(rows[ 0][0])) 它说“假”,对于 MessageBox.Show(Convert.ToString(rows[10][10])) “真”而不是数字,我在这里做错了什么?您的解决方案应该可以工作,我认为它真的很简单 =) 谢谢
  • 你不要ReadAllLines(过早物化),ReadLines会是更好的选择
  • @christian890 我稍微修改了代码。出现错误,因为我没有使用任何数据进行测试并使用 select 而不是 where
  • @christian890 我尝试了你的值,它对我有用......虽然我在值中有很多特殊字符.. 可能是因为我从页面或其他地方复制了它。
  • @christian890 我想知道您是否可以手动创建一个新的 csv 来测试代码,然后检查实际的 csv 是否具有所需的正确换行符.. 我确定有什么文件及其内容有误。
【解决方案2】:

如果您想删除所有包含NAN 的行(CSV 的典型任务 - 清除所有不完整的行),例如

  123.0; 456; 789
    2.1; NAN;  35     <- this line should be removed (has NaN value)
     -5;   3;  18

你可以这样实现

  double[][] data = File
    .ReadLines(filepath)
    .Select(line => line.Split(new char[] {';', '\t'},
                               StringSplitOptions.RemoveEmptyEntries))
    .Where(items => items  // Filter first...
       .All(item => !string.Equals("NAN", item, StringComparison.OrdinalIgnoreCase)))
    .Select(items => items
       .Select(item => double.Parse(item, CultureInfo.InvariantCulture))
       .ToArray()) // ... materialize at the very end
    .ToArray();

使用string.Join 显示行:

 string report = string.Join(Environment.NewLine, data
   .Select(line => string.Join(";", line)));

 Console.Write(report);

编辑:实际问题是仅从 CSV 中获取第二和第三完整列:

NaN;NaN;NaN;NaN
NaN;1;5;NaN
NaN;2;6;NaN
NaN;3;7;NaN
NaN;4;8;NaN
NaN;NaN;NaN;NaN

想要的结果是

[[1, 5], [2, 6], [3, 7], [4, 8]]

实现:

double[][] data = File
  .ReadLines(filepath)
  .Select(line => line
     .Split(new char[] {';'},
            StringSplitOptions.RemoveEmptyEntries)
     .Skip(1) 
     .Take(2)
     .Where(item => !string.Equals("NAN", item, StringComparison.OrdinalIgnoreCase))
     .ToArray())
  .Where(items => items.Length == 2)
  .Select(items => items
    .Select(item => double.Parse(item, CultureInfo.InvariantCulture))
    .ToArray())
  .ToArray();

测试

// 1
Console.Write(data[0][0]);
// 5
Console.Write(data[0][1]);
// 2
Console.Write(data[1][0]);

一次性获取所有值:

string report = string.Join(Environment.NewLine, data
   .Select(line => string.Join(";", line)));

Console.Write(report);

结果:

1;5
2;6
3;7
4;8 

编辑 2:如果您只想提取非 NaN 值(请注意,初始 CSV 结构将被破坏):

1;2;3              1;2;3
NAN;4;5            4;5   <- please, notice that the structure is lost
6;NAN;7        ->  6;7
8;9;NAN;           8;9
NAN;10;NAN         10
NAN;NAN;11         11 

然后

double[][] data = File
  .ReadLines(filepath)
  .Select(line => line
     .Split(new char[] {';'},
            StringSplitOptions.RemoveEmptyEntries)
     .Where(item => !string.Equals("NAN", item, StringComparison.OrdinalIgnoreCase)))
  .Where(items => items.Any()) 
  .Select(items => items
    .Select(item => double.Parse(item, CultureInfo.InvariantCulture))
    .ToArray())
  .ToArray();

【讨论】:

  • @christian890:很抱歉打错了:string.Equals("NAN", item... 我们应该比较 NANitem
  • @christian890:我明白了;如果您想提取第 2 和第 3d 完整行,请查看我的编辑;因为data 是一个锯齿状数组,您可以根据需要获得所需的项目:data[x][y],例如data[0][0] 应该返回 1
  • @christian890:错误的原因是 CSV 中的值既不是NaN 也不是有效的double 值,例如"bla-bla-bla"。能否请您提供实际的 CSV 文件?
  • @christian890:您不仅要删除 NaN,还要删除空值 - .Split(new char[] {';'}, StringSplitOptions.RemoveEmptyEntries)
  • @christian890:不客气!下一次,请从实际数据开始:)
猜你喜欢
  • 2018-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多