代码之家  ›  专栏  ›  技术社区  ›  Oliver

为IList中的每个字符串构建中值<IDictionary<string,double>>

  •  1
  • Oliver  · 技术社区  · 15 年前

    事实上,我有点脑筋急转弯,只是找不到正确的方向让它工作:

    给定是一个 IList<IDictionary<string, double>>

    Name|Value
    ----+-----
    "x" | 3.8
    "y" | 4.2
    "z" | 1.5
    ----+-----
    "x" | 7.2
    "y" | 2.9
    "z" | 1.3
    ----+-----
    ... | ...
    

    var list = CreateRandomPoints(new string[] { "x", "y", "z" }, 20);
    

    其工作原理如下:

    private IList<IDictionary<string, double>> CreateRandomPoints(string[] variableNames, int count)
    {
        var list = new List<IDictionary<string, double>>(count);
        list.AddRange(CreateRandomPoints(variableNames).Take(count));
    
        return list;
    }
    
    private IEnumerable<IDictionary<string, double>> CreateRandomPoints(string[] variableNames)
    {
        while (true)
            yield return CreateRandomLine(variableNames);
    }
    
    private IDictionary<string, double> CreateRandomLine(string[] variableNames)
    {
        var dict = new Dictionary<string, double>(variableNames.Length);
    
        foreach (var variable in variableNames)
        {
            dict.Add(variable, _Rand.NextDouble() * 10);
        }
    
        return dict;
    }
    

    我还可以说,已经确保 列表中的每个字典都包含相同的键 (但是从一个列表到另一个列表,键的名称和计数可以更改)。

    所以这就是我得到的。现在来谈谈我需要的东西:

    我想得到所有字典中每个键的中位数(或任何其他数学聚合运算),以便调用的函数类似于:

    IDictionary<string, double> GetMedianOfRows(this IList<IDictionary<string, double>> list)
    

    最好是给函数提供某种聚合操作作为参数,使其更通用(不知道func是否有正确的参数,但应该想象一下我想做什么):

    private IDictionary<string, double> Aggregate(this IList<IDictionary<string, double>> list, Func<IEnumerable<double>, double> aggregator)
    

    如果列表中有20个变量和1000个值,我不想在列表中重复20次。相反,我会在列表上遍历一次,然后一次计算所有20个变量(这样做的最大优点是也可以将其用作 IEnumerable<T> 列表的任何部分)。

    public static IDictionary<string, double> GetMedianOfRows(this IList<IDictionary<string, double>> list)
    {
        //Check of parameters is left out!
    
        //Get first item for initialization of result dictionary
        var firstItem = list[0];
    
        //Create result dictionary and fill in variable names
        var dict = new Dictionary<string, double>(firstItem.Count);
    
        //Iterate over the whole list
        foreach (IDictionary<string, double> row in list)
        {
            //Iterate over each key/value pair within the list
            foreach (var kvp in row)
            {
                //How to determine median of all values?
            }
        }
    
        return dict;
    }
    

    只是想确定一下这里有一个关于 the Median .

    解决方案

    有了它,我们现在可以做这样美丽的陈述:

    var result0 = list.Cast<IEnumerable<KeyValuePair<string, double>>>()
                      .Transpose()
                      .ToDictionary(column => column.First().Key,
                                    column => column.Select(kvp => kvp.Value)
                                                    .Sum());
    

    var result1 = list.Cast<IEnumerable<KeyValuePair<string, double>>>()
                      .Transpose()
                      .ToDictionary(column => column.First().Key,
                                              //Performing my own function on the IEnumerable<double>
                                    column => GetSumOfElements(column.Select(kvp => kvp.Value)));
    
    private double GetSumOfElements(IEnumerable<double> elements)
    {
        double result = 0;
    
        foreach (var element in elements)
        {
            result += element;
        }
    
        return result;
    }
    
    1 回复  |  直到 15 年前
        1
  •  1
  •   Community Mohan Dere    8 年前
    var list = CreateRandomPoints(new string[] { "x", "y", "z" }, 20);
    
    var result = list.Cast<IEnumerable<KeyValuePair<string, double>>>()
                     .Transpose()
                     .ToDictionary(row => row.First().Key,
                                   row => row.Select(kvp => kvp.Value).Median());
    

    具有 Transpose here ,和 Median here .

    只是想确定一下,这里有一个关于 transpose of a matrix . :-)