前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >数据分析02-数据抽样

数据分析02-数据抽样

作者头像
数据仓库晨曦
发布2024-03-07 12:30:30
1260
发布2024-03-07 12:30:30
举报
文章被收录于专栏:数据仓库技术数据仓库技术

1.样例数据

有数据表t_sample包含ID,type,val三个字段1~10000行数据,type为随机分配的1~3,val为0~1的随机数;其中根据ID进行分10个桶;

建表语句和数据生成语句如下:

代码语言:javascript
复制
set hive.enforce.bucketing=true;
-- 建表语句
CREATE TABLE t_sample (
  id bigint,
  type bigint,
  val double
)
CLUSTERED BY (id) INTO 10 BUCKETS
STORED AS ORC;

--数据插入
insert into t_sample(id,type,val)
select ind+1 as id,floor(rand()*3)+1 as type,rand() as val from(select split(space(9999),'') as a) t lateral view posexplode(a) tt as ind,space_val;

样例数据查看

代码语言:javascript
复制
+-------+-------+----------------------+
|  id   | type  |         val          |
+-------+-------+----------------------+
| 1928  | 1     | 0.8149664325591012   |
| 4320  | 3     | 0.41168841833279834  |
| 5323  | 2     | 0.40307445813137033  |
| 9731  | 1     | 0.2036838175568444   |
| 3915  | 2     | 0.0226902346921094   |
| 659   | 3     | 7.92836807809949E-4  |
| 1299  | 3     | 0.3501926828217895   |
| 2976  | 1     | 0.7974942217644628   |
| 6173  | 3     | 0.2531007613722899   |
| 7462  | 1     | 0.14091100049939698  |
+-------+-------+----------------------+

2.随机抽样

2.1 随机抽取N行

如何随机抽取N行,假设N=10.我们使用rand()函数新生成一列,根据rand()值进行排序,正序倒序均可,然后使用limit限制10行即可。

实现SQL

代码语言:javascript
复制
select
id,
type,
val
from t_sample
order by rand() asc
limit 10

为了验证是随机的,我们执行多次,结果应该是不一样的,这里我们执行两次,下面是结果

2.2抽取一定比例数据(大致)

假设我们不知道总行数,抽0.05%的数据。依旧使用rand()函数,我们知道rand()是随机生成的0~1的数据,所以我们认为如果rand()值小于0.0005 则是抽取的对应比例的数据。当数据量越大的时候,数据也越准确 。所以这里是一个大致结果。因为我们知道数据行数为10000,理论上应该是5条,但是由于我们的数据量比较小,应该会有比较大的偏差。我们还是执行2次,看下结果.

实现SQL

代码语言:javascript
复制
select
id,
type,
val
from t_sample
where rand()<=0.0005

查询结果

2.3抽取一定比例数据 (精确)

如果我们想要精确地抽取对应比例的数据,该怎么办呢?首先需要统计出总的行数cnt,然后使用row_numer()开窗,根据一个rand()进行排序生成序号rn,然后rn/cnt<=0.0005即可。

实现SQL

代码语言:javascript
复制
select
id,
type,
val
from
(select
id,
type,
val,
row_number()over(order by rand()) as rn,
count(1)over() as cnt
from t_sample) t
where rn/cnt <=0.0005

执行结果

2.4分组随机抽样 抽取N行

现在需求进一步增加,我们需要按照type进行分组,然后每组抽取5行数据。这里我们要进行分组排序:使用开窗函数row_number()根据type进行分组,根据rand() 进行排序,然后得到序号rn,限制rn<=5即可。

实现SQL

代码语言:javascript
复制
select
id,
type,
val
from
(select
id,
type,
val,
row_number()over(partition by type order by rand()) as rn
from t_sample)t
where rn <= 5

执行结果

3.分箱抽样

我们假设按照ID进行分箱,共分成5箱,每箱随机抽取2个值。这里我们使用ntile来进行分箱n_box,然后根据n_box进行分组,每组抽取随机抽取2个值。为了方便查看我在sql最后加了按照id排序;

实现SQL,

代码语言:javascript
复制
select
id,type,val
from
(select
id,type,val,n_box,
row_number()over(partition by n_box order by rand()) as rn
from
(select
id,type,val,ntile(5)over(order by id) as n_box
from t_sample
)t
)tt
where rn <=2
order by id asc

执行结果

4.数据块抽样

4.1整体数据块抽样

使用tablesample进行数据块抽样,指的是抽取一块数据。这里不能保证数据的随机性,因为获取数据就是头开始连续获取要的数据内容。我们可以看到多次执行同一个SQL,返回的结果是一致的。例如我抽取5行数据。

实现SQL

代码语言:javascript
复制
select
id,
type,
val
from t_sample
TABLESAMPLE (5 rows)

两次执行结果

4.2分桶数据块抽样

分桶数据块抽样,同样有数据块抽样的特点,但是指定了抽取那个桶的数据。如果总的桶数量和默认表内桶数量一致,则直接从原有桶内抽取指定桶内数据,否则对表内数据重新分桶抽取。

查询SQL

代码语言:javascript
复制
select
id,
type,
val
from t_sample
TABLESAMPLE (BUCKET 1 OUT OF 10)
limit 10

执行结果

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-03-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据仓库技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.样例数据
  • 2.随机抽样
    • 2.1 随机抽取N行
      • 2.2抽取一定比例数据(大致)
        • 2.3抽取一定比例数据 (精确)
          • 2.4分组随机抽样 抽取N行
          • 4.数据块抽样
            • 4.1整体数据块抽样
              • 4.2分桶数据块抽样
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档