Julia:从一个分组的数据帧中采样N个组



我有一个项目产品销售的时间序列记录的数据帧,我正在使用它来绘制,但有很多,我想要一个N.的随机样本

下面是一个包含三个项目的数据的简化示例,我想随机抽取其中两个:

df = DataFrame(time = [0, 1, 0, 1, 0, 1]
, amt = [19.00, 11.00, 35.50, 32.50, 5.99, 5.99]
, item = ["B001", "B001", "B020", "B020", "BX00", "BX00"])
6×3 DataFrame
│ Row │ time  │ amt     │ item   │
│     │ Int64 │ Float64 │ String │
├─────┼───────┼─────────┼────────┤
│ 1   │ 0     │ 19.0    │ B001   │
│ 2   │ 1     │ 11.0    │ B001   │
│ 3   │ 0     │ 35.5    │ B020   │
│ 4   │ 1     │ 32.5    │ B020   │
│ 5   │ 0     │ 5.99    │ BX00   │
│ 6   │ 1     │ 5.99    │ BX00   │

经过一番研究,我找到了一个解决方案,但这似乎不是简单的表达方式。

# this attaches a random number to each group, sorts it, and then ranks each group:
using StatsBase
@pipe df |> groupby(_, :item) |>
combine(_, :time, :amt, :item, :item => (x -> rand()) => :rando) |>
sort(_, :rando) |>
transform(_, :rando => denserank => :rnk_rnd)
6×5 DataFrame
│ Row │ item   │ time  │ amt     │ rando    │ rnk_rnd │
│     │ String │ Int64 │ Float64 │ Float64  │ Int64   │
├─────┼────────┼───────┼─────────┼──────────┼─────────┤
│ 1   │ B001   │ 0     │ 19.0    │ 0.449577 │ 1       │
│ 2   │ B001   │ 1     │ 11.0    │ 0.449577 │ 1       │
│ 3   │ BX00   │ 0     │ 5.99    │ 0.482569 │ 2       │
│ 4   │ BX00   │ 1     │ 5.99    │ 0.482569 │ 2       │
│ 5   │ B020   │ 0     │ 35.5    │ 0.612401 │ 3       │
│ 6   │ B020   │ 1     │ 32.5    │ 0.612401 │ 3       │

# I only need the original columns, and I'll filter for the first N=2 items from the re-constituted dataframe
@pipe ans |> filter(:rnk_rnd => <=(2), _)  |>
select(_, :item, :time, :amt)
4×3 DataFrame
│ Row │ item   │ time  │ amt     │
│     │ String │ Int64 │ Float64 │
├─────┼────────┼───────┼─────────┤
│ 1   │ BX00   │ 0     │ 5.99    │
│ 2   │ BX00   │ 1     │ 5.99    │
│ 3   │ B001   │ 0     │ 19.0    │
│ 4   │ B001   │ 1     │ 11.0    │
# this is exactly what I'm looking for

没有其他更紧凑的方法可以从分组数据帧中随机抽取组样本吗?

另一种选择是使用StatsBase.jsl:中的sample

@pipe df |>
groupby(_, :item) |>
_[sample(1:length(_), 2, replace=false)] |>
DataFrame

如果你从你的DataFrame(不是一个固定的数字(中接受一个随机分数q,那就更容易了:

@pipe df |>
groupby(_, :item) |>
combine(sdf -> rand() < q ? sdf : DataFrame(), _)

我从DataFrames.jl 中的一个问题中获得了一个更紧凑的表达式

@pipe df |> 
groupby(_, :item) |>
_[shuffle(1:end)] |>
combine(_[1:2], :)

这导致了我随机选择的相同组,返回为数据帧:

4×3 DataFrame
│ Row │ item   │ time  │ amt     │
│     │ String │ Int64 │ Float64 │
├─────┼────────┼───────┼─────────┤
│ 1   │ BX00   │ 0     │ 5.99    │
│ 2   │ BX00   │ 1     │ 5.99    │
│ 3   │ B020   │ 0     │ 35.5    │
│ 4   │ B020   │ 1     │ 32.5    │

我认为,如果我们都对这个问题投赞成票,最终会有一个用于分组df的shuffle函数!

最新更新