Python R中求子集的一种有效方法

Python R中求子集的一种有效方法,python,r,Python,R,我正在研究一个金融数据集。数据集有3百万行,对应于3万家公司,包含数字、浮点、分类、字符串等 我的算法要求对给定公司的所有行执行计算。为此,我使用subset函数来标识相关行 但是可以想象,这是非常低效的,因为为了识别子集,R必须遍历所有3M行。如果我对所有3万家公司重复这一步骤,R将遍历数据集3万次,这太可怕了 更好的方法是按公司对数据集进行分组,并能够访问所需的行 我知道我可以在Python中使用字典非常有效地做到这一点,其中键将对应于公司名称,值将是该公司所有行的列表,从而允许我一次性访问

我正在研究一个金融数据集。数据集有3百万行,对应于3万家公司,包含数字、浮点、分类、字符串等

我的算法要求对给定公司的所有行执行计算。为此,我使用subset函数来标识相关行

但是可以想象,这是非常低效的,因为为了识别子集,R必须遍历所有3M行。如果我对所有3万家公司重复这一步骤,R将遍历数据集3万次,这太可怕了

更好的方法是按公司对数据集进行分组,并能够访问所需的行

我知道我可以在Python中使用字典非常有效地做到这一点,其中键将对应于公司名称,值将是该公司所有行的列表,从而允许我一次性访问相关行


但我不知道如何在R中进行类似的高效存储/检索。如有任何帮助/提示,将不胜感激

p Lapointe对data.table的评论恰到好处,我认为你们不会找到更好的。作为比较,我所知道的最好的BaseR方法是通过拆分行索引并在其上子集来生成一个键。这比单独使用子集或分割整个数据帧要快得多。plyr与拆分行索引的速度大致相同。data.table的速度快了几个数量级。计时是在我的系统上从一次运行开始的,我没有适当地进行基准测试

d <- data.frame(company=factor(rep(1:3e4,100)),
                other=round(sample(runif(3e6)),2))

## using subset individually
## 1.8 sec for 10 companies, so ~540 sec total
out0 <- sapply(levels(d$company)[1:10], function(companyi) {
    di <- subset(d, company==companyi)
    mean(di$other)
})

## ## "standard" way; split the data frame and 
## ## the split is prohibitively slow, probably too memory intensive
## ds <- split(d, d$company)
## sapply(ds, function(di) mean(di$other))

## not too bad, but still slow, possibly the best base R method?
## 2.6 sec to do only first 1000 companies, so ~78 sec total
idx <- split(seq_len(nrow(d)), d$company)
out1 <- sapply(idx[1:1000], function(i) mean(d[i,]$other))

## plyr, about the same timing as above
library(plyr)
out2 <- ddply(d[1:1e4,], ~company, summarize, m=mean(other))

## data table is the clear speed demon
## 0.07 sec to do all companies
library(data.table)
DT <- as.data.table(d)
out3 <- DT[, mean(other), keyby=company]

对于大型金融数据集,我将data.table与setkey或setkeyv一起使用。基准测试表明,这是进行计算的最快方法。比python中的dplyr或pandas更快:另外,使用data.table,您可以使用by=company同时对所有公司进行计算,我也讨厌按向下投票方式驾驶;在我看来,对于大多数优秀的StackOverflow系统来说,这不是一个有用的功能。我对否决票的猜测是,他们正在寻找一个样本数据集,就像我在前两行中提供的那样,或者更详细地了解您希望对每家公司进行何种计算。您说您不需要代码,但如果您展示了您当前正在对应用于某些通用数据集的子集所做的操作,那么这将是一个更好的问题。您的编辑应该是注释,而不是对问题主体的编辑…感谢您的注释和回答。100%的人同意,支持分组的包是最好的方式。我要补充的是,很难从问题中得出使用的算法类型,这可能会影响plyr+MCMAPLY之类的算法是否有用。例如,有一个复杂的算法,您可以在进行尽可能多的分组后通过拆分来并行化操作。在这个阶段,下面是我希望对每个公司的行执行的一些示例:1数据清理涉及多种启发式方法,如识别缺少数据的行、从特定类别中筛选行、筛选值小于/大于某个截止值的行、从初始行或最后几行中删除缺少返回的行,确定缺失的月份等。2主要是对这些干净的数据应用不同的回归技术。@Aaron:谢谢你的回答。