【问题标题】:Getting the column totals in a 2D array but it always throws FormatException using C#获取二维数组中的列总计,但它总是使用 C# 抛出 FormatException
【发布时间】:2017-01-24 10:11:16
【问题描述】:

我打算得到一个每列平均值的数组。

但由于 FormatException,我的应用程序在 sum[j] += int.Parse(csvArray[i,j]); 崩溃。我曾尝试使用 Convert.ToDouble 和 Double.Parse 但它仍然会引发该异常。

for loop 中的增量从 1 开始,因为 CSV 数组的 Row 0 and Column 0 是 字符串(名称和时间戳)。对于divisor 或total count of the fields that have values per column,我只计算not BLANK 的字段,因此是IF 语句。我想我需要帮助来处理异常。

以下是我现有的获取平均值的方法。

public void getColumnAverages(string filePath)
        {

            int col = colCount(filePath);
            int row = rowCount(filePath);

            string[,] csvArray = csvToArray(filePath);
            int[] count = new int[col];
            int[] sum = new int[col];
            double[] average = new double[col];

            for (int i = 1; i < row; i++)
            {
                for (int j = 1; j < col; j++)
                {
                    if (csvArray[i,j] != " ")
                    {
                        sum[j] += int.Parse(csvArray[i,j]);
                        count[j]++;
                    }
                }
            }

            for (int i = 0; i < average.Length; i++)
            {
                average[i] = (sum[i] + 0.0) / count[i];
            }

            foreach(double d in average)
            {
                System.Diagnostics.Debug.Write(d);
            }
        }
    }

我已经上传了我在测试原型时使用的CSV file。它在某些列上有BLANK 值。我现有的 IF 语句 无法处理这种情况吗?

还有像1.324556-e09这样的条目,因为我认为是小数位数。我想我必须在csvToArray(filePath) 方法中修剪它,还是有其他有效的方法?谢谢一百万!

【问题讨论】:

  • 那么csvArray[i,j]失败时的值是多少?
  • 这是因为无法将字符串解析为整数,请在csvArray中包含由csvToArray填充的示例数据
  • 我还建议用if(!string.IsNullOrWhitespace(csvArray[i,j]))检查空白,如果它根本不是有效数字,你可以使用int.TryParse来处理
  • @musefan 嗨,我添加了一个屏幕截图。谢谢!
  • @un-lucky 我已经手动检查过了,csvArray[1,1] 的值是“23313”。我不确定为什么它不解析。

标签: c# .net arrays csv multidimensional-array


【解决方案1】:

所以您的代码存在一些问题。格式异常的主要原因是在查看 CSV 文件后,您的数字被引号包围。现在我无法从您的代码中确切地看到您如何将 CSV 文件转换为数组,但我猜您没有清除这些 - 当我第一次使用您的 CSV 并遇到完全相同的错误时我没有.

然后我遇到了一个错误,因为您的 CSV 中的某些值是十进制的,因此无法使用数据类型 int。我假设您仍然想要这些列的平均值,因此在我稍微修改过的方法版本中,我将数组的类型更改为 double。

正如@musefan 建议的那样,我还更改了对空位的检查以使用IsNullOrWhiteSpace 方法。

最后,当您输出结果时,您会收到平均列中第一个值的 NaN,这是因为当您没有考虑到您从未填充数组的第一个位置以免处理字符串值。我不确定您最好如何纠正这种行为,因为我不确定预期的目的 - 这可能没问题 - 所以我暂时没有对此进行任何更改,请在 cmets 中提及如果您需要有关如何排序的帮助!

所以这里是更新的方法:

public static void getColumnAverages(string filePath)
{

    // Differs from the current implementation, reads a file in as text and
    // splits by a defined delim into an array
    var filePaths = @"C:\test.csv";
    var csvArray = File.ReadLines(filePaths).Select(x => x.Split(',')).ToArray();

    // Differs from the current implementation
    var col = csvArray[0].Length;
    var row = csvArray.Length;

    // Update variables to use doubles
    double[] count = new double[col];
    double[] sum = new double[col];
    double[] average = new double[col];
    Console.WriteLine("Started");
    for (int i = 1; i < row; i++)
    {
        for (int j = 1; j < col; j++)
        {
            // Remove the quotes from your array
            var current = csvArray[i][j].Replace("\"", "");

            // Added the Method IsNullOrWhiteSpace
            if (!string.IsNullOrWhiteSpace(current))
            {
                // Parse as double not int to account for dec. values
                sum[j] += double.Parse(current);
                count[j]++;
            }
        }
    }

    for (int i = 0; i < average.Length; i++)
    {
        average[i] = (sum[i] + 0.0) / count[i];
    }

    foreach (double d in average)
    {
        System.Diagnostics.Debug.Write(d + "\n");
    }
}

【讨论】:

  • 非常感谢!关于文件路径,我在 Web 窗体中使用了 FileUpload 控件,因为我必须将它上传到服务器。我想在能够获得平均值数组之后,我看到了一个限制。在现有系统中,它通过第一行的字符串列 搜索specific average。你能帮我想一个解决方法吗?
  • @JPaulPunzalan 我不确定我是否完全理解你遇到的问题,你能解释一下吗?
  • 嗨,今天工作了几个小时后,现在一切正常。我以某种方式想通了。我使用dictionary 来获取特定列标题的列平均值。这里的教训将永远伴随着我。太感谢了! :)
  • @JPaulPunzalan 太棒了!很高兴它有帮助!如果您认为我的回答回答了您的问题,您能否将其标记为正确,谢谢:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-11
  • 1970-01-01
  • 1970-01-01
  • 2022-12-31
  • 1970-01-01
  • 2021-11-26
相关资源
最近更新 更多