我有一些R代码我需要移植到python.然而,R的神奇data.frame和ddply让我无法在python中找到一个好方法.
样本数据(R):
x <- data.frame(d=c(1,1,1,2,2,2),c=c(rep(c('a','b','c'),2)),v=1:6)
Run Code Online (Sandbox Code Playgroud)
样本计算:
y <- ddply(x, 'd', transform, v2=(v-min(v))/(max(v)-min(v)))
Run Code Online (Sandbox Code Playgroud)
样本输出:
d c v v2
1 1 a 1 0.0
2 1 b 2 0.5
3 1 c 3 1.0
4 2 a 4 0.0
5 2 b 5 0.5
6 2 c 6 1.0
Run Code Online (Sandbox Code Playgroud)
所以这是我对那里的pythonistas的问题:你会怎么做?您有一个具有几个重要维度的数据结构.
对于每个(c),并且每个(d)计算(v-min(v))/(max(v)-min(v)))并将其与对应的(d,c)对相关联.
您可以随意使用您想要的任何数据结构,只要它们能够快速处理相当大的数据集(适合内存的数据集).
我想以编程方式组成几个函数.如果这些函数都是相同的类型,我可以执行以下操作:
def a(x: Int): Int = x+1
def b(y: Int): Int = y/2
def c(z: Int): Int = z*4
val f1 = (a _) andThen (b _) andThen (c _)
val f2 = List((a _), (b _), (c _)).reduce(_ andThen _)
Run Code Online (Sandbox Code Playgroud)
在这一点f1并且f2是相同的东西,这编译因为List定义f2是List[Function1[Int,Int]]
但是,如果我想使用相同的基本reduce技术将不同类型的多个兼容函数链接在一起,我会收到错误.
def d(x: Double): Int = x.toInt
def e(y: Int): String = y.toString
def f(z: String): Double = z.toDouble*4
//Works fine
val f3 = (d _) andThen (e _) …Run Code Online (Sandbox Code Playgroud) 我有一个包含200万行和15列的数据框.我想用ddply对这些列中的3个进行分组(所有3个是因子,并且这些因子有780,000个唯一组合),并获得3列的加权平均值(权重由我的数据集定义).以下是相当快的:
system.time(a2 <- aggregate(cbind(col1,col2,col3) ~ fac1 + fac2 + fac3, data=aggdf, FUN=mean))
user system elapsed
91.358 4.747 115.727
Run Code Online (Sandbox Code Playgroud)
问题是我想使用weighted.mean而不是mean来计算我的聚合列.
如果我在同一个数据框上尝试以下ddply(注意,我转换为不可变),以下内容在20分钟后没有完成:
x <- ddply(idata.frame(aggdf),
c("fac1","fac2","fac3"),
summarise,
w=sum(w),
col1=weighted.mean(col1, w),
col2=weighted.mean(col2, w),
col3=weighted.mean(col3, w))
Run Code Online (Sandbox Code Playgroud)
这个操作似乎是CPU饥饿,但不是很密集的RAM.
编辑:所以我最后编写了这个小函数,它利用加权平均值的某些属性"欺骗"了一些,并对整个对象进行乘法和除法,而不是对切片进行.
weighted_mean_cols <- function(df, bycols, aggcols, weightcol) {
df[,aggcols] <- df[,aggcols]*df[,weightcol]
df <- aggregate(df[,c(weightcol, aggcols)], by=as.list(df[,bycols]), sum)
df[,aggcols] <- df[,aggcols]/df[,weightcol]
df
}
Run Code Online (Sandbox Code Playgroud)
当我跑:
a2 <- weighted_mean_cols(aggdf, c("fac1","fac2","fac3"), c("col1","col2","col3"),"w")
Run Code Online (Sandbox Code Playgroud)
我获得了良好的性能,并且有些可重用,优雅的代码.