如何规范化 float 集合,使所有元素的总和为 X
How to normalize a float collection such that the sum of all elements is X
如果这个问题措辞不当或者解决方案很简单,请原谅我。我似乎找不到使用我熟悉的术语搜索的现有答案。
我有一个非负浮点数数组,我想对它们进行归一化 - 我能做的就这些。我的问题是,我希望集合中所有元素的总和为特定数量。
我可以设想实现此目标的丑陋方法,但我只知道有一种 "right" 方法可以实现。目的是创建一个总宽度必须固定的复合条形图。集合中的每个数据点都分配了一种颜色,该颜色应占总条形图宽度的 N%。我受限于图表显示方式。
如果需要代码,最好使用 C# 示例。
// normalize data
var ratio = 100.0 / widths.Max();
var normalizedList = widths.Select(o => o * ratio).ToList();
// magic happens here such that the sum of all elements is N
// and the relative scale of each sibling element is preserved
非常感谢您的帮助,
补充信息:
该图是复合(分段)条形图。 float 集合的每个元素对应一个段。 http://oi62.tinypic.com/2vskt8m.jpg
元素之和为N法则的必要性与作图方法有关,本人权限有限。
为了达到我想要的宽度(由这个 float 集合驱动的图形视觉效果),所有元素的总和必须是一个特定的数字,因此要进行归一化。但是,元素的数量和它们的值都会发生变化,我不清楚如何以任何其他方式对此进行补偿。出于许多无关的原因,以任何其他方式缩放图形视觉效果以避免这种混乱是不可取的。
可能有更完善的方法来解决这个问题,但是:
- 基于 1 对整个集合进行归一化
- 计算归一化集合的总和作为Sum。
- 将每一项乘以 (DesiredSum / Sum)
我没试过,只是 运行 我脑海中的几个基本示例,但它应该涵盖它。
我相信数学方程会是
s= s0 + s1 + s2 + ...
a= size / s
a * s = a* (s0 + s1 + s2 + ...)
a * s = a*s0 + a*s1 + a*s2 + ...
所以这应该可以解决问题
var total = widths.Sum();
var size=100;
var ratio = size/total; //a in the equation
var normalizedList = widths.Select(o => o * ratio).ToList();
var normalSum = normalizedList.Sum(); //should be equal to size
我认为你的比例有点不对。你需要的是你想要的总数除以所有元素的总和。例如
int desiredTotal = 300;
float[] widths = new float[] { 35f, 63f, 12f };
float ratio = desiredTotal / widths.Sum();
var normalizedList = widths.Select(o => o * ratio).ToList();
foreach (var item in normalizedList)
{
Console.WriteLine(item);
}
Console.WriteLine(normalizedList.Sum());
/* Which prints:
95.45454
171.8182
32.72727
300
*/
如果这个问题措辞不当或者解决方案很简单,请原谅我。我似乎找不到使用我熟悉的术语搜索的现有答案。
我有一个非负浮点数数组,我想对它们进行归一化 - 我能做的就这些。我的问题是,我希望集合中所有元素的总和为特定数量。
我可以设想实现此目标的丑陋方法,但我只知道有一种 "right" 方法可以实现。目的是创建一个总宽度必须固定的复合条形图。集合中的每个数据点都分配了一种颜色,该颜色应占总条形图宽度的 N%。我受限于图表显示方式。
如果需要代码,最好使用 C# 示例。
// normalize data
var ratio = 100.0 / widths.Max();
var normalizedList = widths.Select(o => o * ratio).ToList();
// magic happens here such that the sum of all elements is N
// and the relative scale of each sibling element is preserved
非常感谢您的帮助,
补充信息: 该图是复合(分段)条形图。 float 集合的每个元素对应一个段。 http://oi62.tinypic.com/2vskt8m.jpg
元素之和为N法则的必要性与作图方法有关,本人权限有限。
为了达到我想要的宽度(由这个 float 集合驱动的图形视觉效果),所有元素的总和必须是一个特定的数字,因此要进行归一化。但是,元素的数量和它们的值都会发生变化,我不清楚如何以任何其他方式对此进行补偿。出于许多无关的原因,以任何其他方式缩放图形视觉效果以避免这种混乱是不可取的。
可能有更完善的方法来解决这个问题,但是:
- 基于 1 对整个集合进行归一化
- 计算归一化集合的总和作为Sum。
- 将每一项乘以 (DesiredSum / Sum)
我没试过,只是 运行 我脑海中的几个基本示例,但它应该涵盖它。
我相信数学方程会是
s= s0 + s1 + s2 + ...
a= size / s
a * s = a* (s0 + s1 + s2 + ...)
a * s = a*s0 + a*s1 + a*s2 + ...
所以这应该可以解决问题
var total = widths.Sum();
var size=100;
var ratio = size/total; //a in the equation
var normalizedList = widths.Select(o => o * ratio).ToList();
var normalSum = normalizedList.Sum(); //should be equal to size
我认为你的比例有点不对。你需要的是你想要的总数除以所有元素的总和。例如
int desiredTotal = 300;
float[] widths = new float[] { 35f, 63f, 12f };
float ratio = desiredTotal / widths.Sum();
var normalizedList = widths.Select(o => o * ratio).ToList();
foreach (var item in normalizedList)
{
Console.WriteLine(item);
}
Console.WriteLine(normalizedList.Sum());
/* Which prints:
95.45454
171.8182
32.72727
300
*/