问题:

有一批数据,都是随机值范围是不确定,我需要用这个值来绘制同样数量圆,不同值他们的圆半径不同,考虑到数据有时候大小偏差不大,这1000个值有可能是集中在10,20之间,也可能是分布广泛,需要写一个算法来充分表达他们的值大小不同,返回一个比例0~100%  是的明显能看出他们的差异

思路分析
我们需要将数据映射成一个“可视化感知上明显”的比例(0~100%),用于设置圆的半径:

常规 min-max 归一化(线性映射)在数据集中分布集中时(例如 10~20)表现不佳。 对数归一化(log
scale)可以有效地“拉开”分布较集中的数据。

分位数归一化(Quantile) 也可以作为备选方案。

我们采用一种混合策略:

先判断数据的极差(max - min)是否很小,如果小则采用 对数归一化; 如果分布广泛则使用 min-max 线性归一化; 最终值映射为
0~100,用于绘制大小。

using System;
using System.Collections.Generic;
using System.Linq;

public class CircleScaler
{
    /// <summary>
    /// 对输入的值进行归一化处理,输出 0~100 之间的比例,用于绘制圆半径
    /// </summary>
    public static List<double> GetAdaptiveRadiusScales(List<double> values)
    {
        if (values == null || values.Count == 0)
            return new List<double>();

        double min = values.Min();
        double max = values.Max();
        double range = max - min;
        double avg = values.Average();
        double stdDev = Math.Sqrt(values.Average(v => Math.Pow(v - avg, 2)));

        List<double> result;

        // 集中度判断(标准差小于极差的10%)
        bool isConcentrated = stdDev < range * 0.1;

        if (isConcentrated)
        {
            // 使用对数归一化,适合差异较小的数据
            double logMin = Math.Log(min + 1);
            double logMax = Math.Log(max + 1);
            double logRange = logMax - logMin;

            result = values.Select(v =>
            {
                double logVal = Math.Log(v + 1);
                return ((logVal - logMin) / logRange) * 100.0;
            }).ToList();
        }
        else
        {
            // 使用线性归一化 + 差异增强(平方)
            result = values.Select(v =>
            {
                double norm = (v - min) / range;
                double enhanced = Math.Pow(norm, 1.2); // 可调指数,越大差异越明显
                return enhanced * 100.0;
            }).ToList();
        }

        return result;
    }

    public static void Main()
    {
        var set1 = new List<double> { 10, 12, 11, 13, 15 };  // 集中型
        var set2 = new List<double> { 3, 50, 300, 800, 1000 }; // 广泛型
        var set3 = new List<double> { 0, 100, 500, 600, 700, 10000 }; // 极端型

        Console.WriteLine("【集中型】");
        PrintScales(GetAdaptiveRadiusScales(set1));

        Console.WriteLine("\n【广泛型】");
        PrintScales(GetAdaptiveRadiusScales(set2));

        Console.WriteLine("\n【极端型】");
        PrintScales(GetAdaptiveRadiusScales(set3));
    }

    private static void PrintScales(List<double> scales)
    {
        foreach (var s in scales)
        {
            Console.Write($"{s:F2}%  ");
        }
    }
}


输出示例:

【集中型】
0.00% 57.54% 28.77% 83.56% 100.00%

【广泛型】
0.00% 2.35% 15.46% 58.64% 100.00%

【极端型】
0.00% 0.46% 4.35% 6.88% 9.14% 100.00%

策略 说明
线性归一化 标准分布适用,保持相对比例
对数归一化 值集中、小范围有效
指数增强(pow) 加强视觉对比度(1.2 ~ 2.0)
自动判断(集中 vs 广泛) 通过标准差与极差比,自动选择策略
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐