【问题标题】:Find out minimum value from a multidimensional array with NaNs从具有 NaN 的多维数组中找出最小值
【发布时间】:2013-03-01 23:02:18
【问题描述】:

我有一个二维数组 (double[ , ]),我想知道最小值是多少。我尝试了 Linq.Select.Min,但由于我的数组通常包含 NaN 值,因此 minvalue 始终是 NaN

所以,我需要一些方法来找到“跳过”NaN 的最小值。

非常感谢任何帮助!

【问题讨论】:

    标签: c# multidimensional-array nan min


    【解决方案1】:

    今天是扩展方法的日子!使用它在您的所有double[,] 上拥有一个通用的Min() 函数!

    这里有一些通用的 [,] 扩展。请注意,这仅适用于实现IComparable的类型

    这个什么都忽略:

    public static T Min<T>(this T[,] arr) where T : IComparable
    {
        bool minSet = false;
        T min = default(T);
        for (int i = 0; i < arr.GetLength(0); i++)
            for (int j = 0; j < arr.GetLength(1); j++)
                if (!minSet)
                {
                    minSet = true;
                    min = arr[i, j];
                }
                else if (arr[i, j].CompareTo(min) < 0)
                    min = arr[i, j];
        return min;
    }
    

    这会让你指定一个要忽略的值,并且在数组只包含被忽略值的特殊情况下,它会返回被忽略的值。

    public static T Min<T>(this T[,] arr, T ignore) where T : IComparable
    {
        bool minSet = false;
        T min = default(T);            
        for (int i = 0; i < arr.GetLength(0); i++)
            for (int j = 0; j < arr.GetLength(1); j++)
                if (arr[i, j].CompareTo(ignore) != 0)
                    if (!minSet)
                    {
                        minSet = true;
                        min = arr[i, j];
                    }
                    else if (arr[i, j].CompareTo(min) < 0)
                        min = arr[i, j];
        return (minSet) ? min : ignore;
    }
    

    下面代码的输出是

    NaN
    -10

    double[,] d = new double[5, 5]
    {
        { 0, 1, 2, 3, 4 },
        { 5, 6, 7, 8, 9 },
        { 10, 11, -10, 12, 13 },
        { 14, 15, 16, 17, 18 },
        { 19, double.NaN, 21, 22, 23 }
    };
    Console.WriteLine(d.Min());
    Console.WriteLine(d.Min(double.NaN));
    

    【讨论】:

    • 有趣...您认为这与更高级别的 LINQ 方法相比如何?
    • 它可能会稍微快一些,除非在 LINQ 库中有一些我不知道的幕后优化(在这种情况下我怀疑)。在 LINQ 版本中,您还使用 Select 创建 N 多个 IEnumerable,其中 N 是数组第一个维度的长度。
    • 我对此进行了测试,它确实有效。我很容易接受这一点,除非有人提出了一个非常聪明的 LINQ 表达式,它也可以工作......
    • (顺便说一句,你认为这个扩展是否可以用于任意维数的任何数组?)
    • 是的,我会在一分钟内重写它
    【解决方案2】:

    试试这个:

    var minvalue = System.Linq.Enumerable.Range(0, 4)
        .Where(i => !Double.IsNa(myarray[i,1]))
        .Select(i => myarray[i, 1]).Min();
    

    更新:

      double[,] myarray = new double[4,4];
    
      var rows = myarray.GetLength(0);
      var cols = myarray.GetLength(1);
    
      Enumerable.Range(0, rows * cols)
        .Where(i => !Double.IsNaN(myarray[i/rows, i%rows]))
        .Select(i => myarray[i/rows, i%rows])
        .Min();
    

    .Range() 的更高级用法无疑是可能的,我现在将对其进行研究。

    【讨论】:

    • 我编辑了这个问题。 Range(0,4) 不应该在那里(它是复制粘贴的),我不确定提供的代码在两个维度上都有效。您能否编辑您的答案以考虑通用二维数组?我很乐意接受。
    • 您正在寻找所有单元格中的最小值,两个维度?
    • 是的。让我们假设数组是地形的数字高程模型(它就是这样),在网格中有一些无效值。我想找到地形的“最低”海拔(不管它的位置)。
    【解决方案3】:
    public static double MinIsNumber(double[,] array)
    {
        return array.Cast<double>()
            .Where(n => !double.IsNaN(n))
            .Min();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-28
      • 1970-01-01
      • 2016-01-31
      • 1970-01-01
      • 2022-07-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多