如何将数值列表分组为范围?

机器算法验证 擅长 sql
2022-03-20 20:11:33

我确实有一个很大的数值列表(包括重复项),我确实想将它们分组到范围中,以查看它们是否分布。

假设有 1000 个值,范围从 0 到 2.000.000,我确实想对它们进行分组。

我怎样才能做到这一点,最好是在 Excel 或 SQL 中。

4个回答

为什么要对它们进行分组?相反,如何估计数据产生的分布的概率密度函数 (PDF)?这是一个基于 R 的示例:

set.seed(123)
dat <- c(sample(2000000, 500), rnorm(100, 1000000, 1000), 
         rnorm(150, 1500000, 100),rnorm(150, 500000, 10),
         rnorm(180, 10000, 10), rnorm(10, 1000, 5), 1:10)
dens <- density(dat)
plot(dens)

如果数据是严格有界的(0, 2,000,000),那么核密度估计可能不是最适合的。您可以通过要求它仅评估边界之间的密度来捏造事情:

dens2 <- density(dat, from = 0, to = 2000000)
plot(dens2)

或者有直方图 - 内核密度的粗略版本。您具体谈论的是对数据进行分箱。有很多规则/方法可以从数据中选择等宽的 bin(即 bin 的数量)。在 R 中,默认的是 Sturges 规则,但它也包括 Freedman-Diaconis 规则和 Scott 规则。还有其他的 - 请参阅直方图上的 Wikipedia 页面。

hist(dat)

如果您对核密度图或直方图本身不感兴趣,而只是对分箱数据不感兴趣,那么您可以使用nclass.X函数族计算分箱数,其中X之一然后使用bin 您的数据:SturgesscottFDcut()

cut.dat <- cut(dat, breaks = nclass.FD(dat), include.lowest = TRUE)
table(cut.dat)

这使:

> cut.dat
  [-2e+03,2.21e+05] (2.21e+05,4.43e+05] (4.43e+05,6.65e+05] (6.65e+05,8.88e+05] 
                247                  60                 215                  61 
(8.88e+05,1.11e+06] (1.11e+06,1.33e+06] (1.33e+06,1.56e+06] (1.56e+06,1.78e+06] 
                153                  51                 205                  50 
   (1.78e+06,2e+06] 
                 58

在 R。

然而,分箱充满了问题,最明显的是;你怎么知道你选择的 bin 并没有影响你对数据分布方式的印象?

我假设您已经确定了要使用的类别数量。假设您要使用 20 个类别。然后他们将是:

  • 类别 1:[0 - 100,000)
  • 类别 2:[100,000 - 200,000)
  • 第三类:[200,000 - 300,000)
  • ...
  • 第 19 类:[1,800,000 - 1,900,000)
  • 第 20 类:[1,900,000 - 2,000,000]

注意每个类别的标签可以定义为

FLOOR (x / category_size) + 1

这很容易定义为 SQL 中的计算列或 Excel 中的公式。

请注意,最后一个类别比其他类别大得多,因为它在两侧都是封闭的。如果您碰巧得到的值正好是 2,000,000,您可能会错误地将其归类为第 21 类,因此您必须用丑陋的“IF”(在 Excel 中)或“CASE”(在 SQL 中)来处理这个异常。

另一个使用 Excel 的选项是函数,它可以让您在 bin 的数量和大小方面具有相当大的灵活性=frequency(data_array, bins_array)它是一个需要两个参数的数组函数。第一个参数是您的数据,第二个参数是您定义的箱。

假设您的数据位于单元格 A1 - A1000 中,并在单元格 B1 - B20 中创建 bin。您可能希望突出显示单元格 C1-C21,然后键入类似=FREQUENCY(A1:A100, B1:B21). 与普通函数不同,数组函数必须使用组合键输入SHIFT + CTRL + ENTER如果没有,您应该会看到所有箱子的计数都已填满 - 您很可能只按 Enter 键并计算第一个单元格。

网上有很多很好的教程,更详细地解释了这一点,这是一个不错的教程

您已请求 Excel 或 SQL 解决方案。Excel 中最简单的方法是使用其“分析”插件来创建直方图。它将自动创建箱(值的范围),但可选地,接受箱切点列表作为输入并使用它们。输出包括 bin 计数的并行列表。这对于不规则宽度的垃圾箱特别方便。

这是一次性计算:如果数据更改或切点更改,您必须再次浏览整个对话框。一个更灵活的选项是使用 COUNTIF 来计算小于或等于任何给定 bin 切点的所有值。这种数组的第一个差异给出了 bin 计数。

这是一个工作示例。数据位于名为“Simulation_Z”的列中(在这种特殊情况下,它被定义为一整列,例如$C:$C)。下面显示的公式是从同一工作簿中工作表的 L2:N10 列复制而来的。它们是通过向下复制第一个而创建的(但请注意 N3 中第一个计数的特殊公式)。

Cut Count up                            Count
-3.0    =COUNTIF(Simulation_Z, "<=" & L3)   =M3
-2.0    =COUNTIF(Simulation_Z, "<=" & L4)   =M4-M3
-1.0    =COUNTIF(Simulation_Z, "<=" & L5)   =M5-M4
 0.0    =COUNTIF(Simulation_Z, "<=" & L6)   =M6-M5
 1.0    =COUNTIF(Simulation_Z, "<=" & L7)   =M7-M6
 2.0    =COUNTIF(Simulation_Z, "<=" & L8)   =M8-M7
 3.0    =COUNTIF(Simulation_Z, "<=" & L9)   =M9-M8
=MAX(Simulation_Z)  =COUNTIF(Simulation_Z, "<=" & L10)  =M10-M9

L 列(“Cut”)规定了每个 bin 的上限

该过程同时定义了 bin 并计算了它们的计数,然后可用于进一步的测试(例如\)或绘图。χ-squared