为什么python在编辑列属性方面比r快得多



我一直在使用spotfire,并意识到我的python代码编辑列属性的速度比r代码快得多。r代码大约需要24秒,而python代码做同样的事情大约需要4秒。是不是我的r代码写得不好,导致了这种情况的发生。

以下是我的python代码示例:

start=time.time()
count=0
names=[]
for i in olddt.Columns: #getting columns from old data table
names.append(i)
for i in dt.Columns: #assigning new values
if count<=4:
i.Properties["Limits.Whatif.Upper"]=1.0
i.Properties["Limits.Whatif.Lower"]=1.0
i.Properties["Limits.Prod.Upper"]=1.0
i.Properties["Limits.Prod.Lower"]=1.0
count=count+1
else:
i.Properties["Limits.Whatif.Upper"]=float(count-4)+26.0
i.Properties["Limits.Whatif.Lower"]=float(count-4)-39.0
i.Properties["Limits.Prod.Upper"]=names[count-4].Properties["Limits.Whatif.Upper"]+5.0
i.Properties["Limits.Prod.Lower"]=names[count-4].Properties["Limits.Whatif.Lower"]-4.0
count=count+1
print time.time()-start

这是我的R代码:

for(col in 1:ncol(temp2)){
if (col<=4){
attributes(temp2[,col])$SpotfireColumnMetaData$upper=Inf
attributes(temp2[,col])$SpotfireColumnMetaData$lower=-1*Inf
attributes(temp2[,col])$SpotfireColumnMetaData$upper2=Inf
attributes(temp2[,col])$SpotfireColumnMetaData$lower2=-1*Inf
}
else{
names(attributes(dt[,col-4])$SpotfireColumnMetaData)<- lapply( names( attributes(dt[ ,col-4] )$SpotfireColumnMetaData), tolower)
attributes(temp2[,col])$SpotfireColumnMetaData$upper=2
attributes(temp2[,col])$SpotfireColumnMetaDatalower=1
attributes(temp2[,col])$SpotfireColumnMetaData$upper2=attributes(dt[,col-4])$SpotfireColumnMetaData$upper
attributes(temp2[,col])$SpotfireColumnMetaData$lower2=attributes(dt[,col-4])$SpotfireColumnMetaData$lower
}
}

我还使用了一个在这里看到的lapply函数:

applyLimits <- function(col){
if (count<4){
attributes(temp2[,col])$SpotfireColumnMetaData$upper<<-Inf
attributes(temp2[,col])$SpotfireColumnMetaData$lower<<- (-1*Inf)
attributes(temp2[,col])$SpotfireColumnMetaData$upper2<<-Inf
attributes(temp2[,col])$SpotfireColumnMetaData$lower2<<- (-1*Inf)
count<<-count+1
}
else{
attributes(temp2[,col])$SpotfireColumnMetaData$upper<<-2
attributes(temp2[,col])$SpotfireColumnMetaData$lower<<-1
attributes(temp2[,col])$SpotfireColumnMetaData$upper2<<-attributes(dt[,col-4])$SpotfireColumnMetaData$upper2
attributes(temp2[,col])$SpotfireColumnMetaData$lower2<<-attributes(dt[,col-4])$SpotfireColumnMetaData$lower2
count<<-count+1
}
}
lapply(1:ncol(temp),applyLimits)

如果有什么方法可以改进我的r代码,请告诉我,但我还没有看到更好的方法来调整它的属性。根据一些研究,我已经做了temp2和dt都应该是data.frame

记住R是一种矢量化语言,您的lapply函数不是矢量化的。为了获得良好的性能,您需要lapply返回一个向量并一次性更新整个向量。您的函数一次更新一行和一列,这就是性能不佳的原因。

矢量化方法是四个lapply调用,每个调用更新一整列。应该看起来有点像这样:

applyLimits1 <- function(col){
count <<- count+1
if (count<4) Inf else 2 
}
applyLimits2 <- function(col){
count <<- count+1
if (count<4) (-1*Inf) else 1 
}
applyLimits3 <- function(col){
count <<- count+1
if (count<4) Inf else attributes(dt[,col-4])$SpotfireColumnMetaData$upper2
}
applyLimits4 <- function(col){
count <<- count+1
if (count<4) (-1*Inf) else attributes(dt[,col-4])$SpotfireColumnMetaData$lower2
}
count <- -1
attributes(temp2[,col])$SpotfireColumnMetaData$upper <- lapply(1:ncol(temp),applyLimits1)
count <- -1
attributes(temp2[,col])$SpotfireColumnMetaData$lower <- lapply(1:ncol(temp),applyLimits2)
count <- -1
attributes(temp2[,col])$SpotfireColumnMetaData$upper2 <- lapply(1:ncol(temp),applyLimits3)
count <- -1
attributes(temp2[,col])$SpotfireColumnMetaData$lower2 <- lapply(1:ncol(temp),applyLimits4)

我没有要测试的数据,我只是把你的代码粘贴了一下。你可能会更好地使用sapply或vapply。当然,有些语言比其他语言更适合某些任务。。。

最新更新