我有一个包含大量值(53,000,000+)的数据文件,我想提取这些值中n 个的随机子集(例如 2,000,000)。我实现了一个 Perl 脚本,它将列表拉入内存,使用Fisher-Yates 方法对数组进行洗牌,然后打印出洗牌列表中的前n个值。然而,即使在较小的测试集(50,000 个值)上,这种改组过程也需要花费大量时间。
我正在寻找一种更有效、可扩展的方法来识别大量值的随机子集并将其打印出来。有什么建议么?
更新:根据答案和更多搜索,看起来正确的术语是“随机采样”。
我在使用基于 Metropolis-Hastings 算法的 MCMC 技术对后验分布进行采样(因此是贝叶斯方法)方面很新。为此,我在 R 中使用了 mcmc 库。我的分布是多维的。为了检查这个metro算法是否适用于多元分布,我在一个多维student-t分布(包mvtnorm,函数dmvt)上成功地做到了。现在我想对我的多元分布(2 个变量 x 和 y)应用同样的东西,但它不起作用;我收到一个错误:X[, 1] 中的错误:维数不正确
这是我的代码:
library(mcmc)
library(mvtnorm)
my.seed <- 123
logprior<-function(X,...)
{
ifelse( (-50.0 <= X[,1] & X[,1]<=50.0) & (-50.0 <= X[,2] & X[,2]<=50.0), return(0), return(-Inf))
}
logpost<-function(X,...)
{
log.like <- log( exp(-((X[,1]^2 + X[,2]^2 - 4)/10 )^2) * sin(4*atan(X[,2]/X[,1])) )
log.prior<-logprior(X)
log.post<-log.like + log.prior # if flat prior, the posterior distribution is the likelihood one
return (log.post)
}
x <- seq(-5,5,0.15)
y <- seq(-5,5,0.15)
X<-cbind(x,y)
#out <- metrop(function(X) …Run Code Online (Sandbox Code Playgroud) 我有一个包含 663 个元素的向量。我想从等于向量长度(即 663)的向量中创建随机样本。换句话说,我想从 663 个元素的所有可能排序中随机抽取样本。我的目标是创建 N 个随机样本或随机选择的排列的数据框。
我尝试了以下方法:
library(combinat)
perms <- as.data.frame(permn(1:663))
Run Code Online (Sandbox Code Playgroud)
由于有这么多可能的排列,我会收到一条错误消息。
我的下一个想法是创建一个数据框,其行数与我想要的样本/排列一样多,变量与元素一样多(即 663),并使用像sapply()with sample(). 但是,我认为这种方法效率不高。
我也试过:
samples <- replicate(100, table(sample(1:663, 663,replace = F)))
Run Code Online (Sandbox Code Playgroud)
但我只得到一个包含 100 列的数据框。
我一直认为set.seed()只让随机变量生成器(例如,rnorm)为任何特定的输入值集生成唯一的序列。
但是,我想知道,为什么当我们设置set.seed(), 然后函数sample()不能正确完成它的工作?
具体来说,鉴于下面的例子,有没有一种方法可以set.seed在之前使用,rnorm但如果多次运行,sample仍然会从中产生新的随机样本?rnormsample
set.seed(123458)
x.y = rnorm(1e2)
sampled = sample(x = x.y, size = 20, replace = TRUE)
plot(sampled)
Run Code Online (Sandbox Code Playgroud) 对于一个项目,我需要创建包含属性之间特定依赖关系的综合分类数据。这可以通过从预定义的贝叶斯网络中采样来完成。在互联网上进行了一些探索后,我发现这Pomegranate是贝叶斯网络的一个很好的包,但是 - 就我而言 - 从这样一个预定义的贝叶斯网络中采样似乎是不可能的。例如,model.sample()引发 a NotImplementedError(尽管此解决方案是这样说的)。
有谁知道是否有一个库可以为贝叶斯网络的构建和采样提供良好的接口?
我有一大组多边形(大约 20k),我想从中采样点。我使用R 中的包st_sample中的函数sf,但它非常慢。从所有多边形中采样大约需要 5 分钟,而且我需要多次重复此任务 (N >= 1000),因此不切实际。
有没有办法进行更快的采样?
我有一个包含D实例数据集的Pandas DataFrame ,这些实例都具有一些连续值x。x以某种方式分布,比如说统一,可以是任何东西。
我想提请n样本D用于其x拥有的目标分配,我可以品尝或近似。这是来自一个数据集,这里我只取正态分布。
如何从中采样实例,D使得样本中的分布x等于/类似于我指定的任意分布?
现在,我对一个 value x,子集进行采样,D以便它包含所有内容x +- eps并从中采样。但是当数据集变大时,这很慢。人们一定想出了一个更好的解决方案。也许解决方案已经很好,但可以更有效地实施?
我可以分成x层,这样会更快,但是没有这个有解决方案吗?
我当前的代码运行良好但速度很慢(30k/100k 为 1 分钟,但我有 200k/700k 左右。)
import numpy as np
import pandas as pd
import numpy.random as rnd
from matplotlib import pyplot as plt
from tqdm import tqdm
n_target = 30000
n_dataset = 100000
x_target_distribution = rnd.normal(size=n_target)
# In reality this would be x_target_distribution = my_dataset["x"].sample(n_target, …Run Code Online (Sandbox Code Playgroud) 作为我上一个问题的后续问题,我对提高现有递归采样函数的性能感兴趣。
递归采样是指为给定的暴露 ID 随机选择最多 n 个唯一的未暴露 ID,然后从剩余的未暴露 ID 中随机选择最多 n 个唯一的未暴露 ID 为另一个暴露 ID。如果给定的公开 ID 没有剩余的未公开 ID,则该公开 ID 将被忽略。
原函数如下:
recursive_sample <- function(data, n) {
groups <- unique(data[["exposed"]])
out <- data.frame(exposed = character(), unexposed = character())
for (group in groups) {
chosen <- data %>%
filter(exposed == group,
!unexposed %in% out$unexposed) %>%
group_by(unexposed) %>%
slice(1) %>%
ungroup() %>%
sample_n(size = min(n, nrow(.)))
out <- rbind(out, chosen)
}
out
}
Run Code Online (Sandbox Code Playgroud)
我能够创建一个更有效的,如下所示:
recursive_sample2 <- function(data, n) {
groups <- unique(data[["exposed"]]) …Run Code Online (Sandbox Code Playgroud) 我想从有界域中的"zipf"分发中进行抽样.
也就是说,假设域是{1,...,N},我想要选择域中的每个元素i,其概率与其成比例i ** -a,其中a是分布的参数.
numpy 提供了一个zipf采样器(numpy.random.zipf),但它不允许我限制域.
我怎样才能从这种分布中轻松抽样?
如果分布参数,, a大于1,我可以numpy通过拒绝(并重新采样)所有大于的样本来使用采样器N.但是,由于它不限制样本范围,因此尝试使用任何较小的值a都不起作用.
当域是有限的时,使用这样的as 应该没有问题,这就是我的应用程序所需要的.
sampling ×10
r ×6
random ×4
python ×3
performance ×2
bayesian ×1
dataframe ×1
distribution ×1
geospatial ×1
mcmc ×1
pandas ×1
permutation ×1
pomegranate ×1
probability ×1
r-sf ×1
resampling ×1
statistics ×1