我在Stackoverflow的第一个问题:)我希望你能够帮助我。
我试图在数据集中找到每月连续最长的雨天数,将雨总量相加,然后存储下雨持续的天数和矩阵中的雨量之和。我成功地获得了下雨天数并将其存储起来,但是一个场景和283点需要2.5小时才能运行(12个模型x 4个场景要跟随:)。我读到某处读取和写入矩阵是低效的,所以我的猜测是操作可能更有效。
此链接在longest consecutive的路上已经有所帮助,但我的问题更进一步。
对于这个问题,最好使用2年的每日降雨量值,我将其与日期相关联,以找出每个月和每年最长的连续阴雨天数。我将输出写入矩阵。然后在盆地中进行了10分。
用于获取连续数字并将其写入矩阵的函数:
WriteRainyDaysCountToMatrix <- function(myDataFrame, myDates, mymatrix, i)
{
monthsAmount <- 24
for (monthNumber in 1:monthsAmount){
#print(cat("monthNumber = ", monthNumber))
year <- toString(myDates[monthNumber,2])
month <- toString(myDates[monthNumber,1])
dayCounter <- 0
precipitationMax <- 0
lastRowPrecipitation <- F
for (rowNumber in 1:nrow(myDataFrame)){
rowDate <- myDataFrame[rowNumber,1]
rowYear <- substr(rowDate,1,4)
rowMonth <- substr(rowDate,5,6)
if (rowYear == year && rowMonth == month){
rowPrecipitation <- myDataFrame[rowNumber,2]
if (rowPrecipitation > 0){
dayCounter <- dayCounter + 1
lastRowPrecipitation <- T
}
else{
if (lastRowPrecipitation == T && precipitationMax == 0){
precipitationMax <- dayCounter
dayCounter <- 0
lastRowPrecipitation <- F
}
else if (lastRowPrecipitation == T && precipitationMax < dayCounter){
precipitationMax <- dayCounter
dayCounter <- 0
lastRowPrecipitation <- F
}
else{
dayCounter <- 0
lastRowPrecipitation <- F
}
}
}
}
if (lastRowPrecipitation == T && precipitationMax == 0){
precipitationMax <- dayCounter
}
mymatrix[[monthNumber,i]] <- precipitationMax
}
return (mymatrix)
}
此处定义了存储值的空矩阵:
pmatrix_hist <- matrix(data=NA,nrow=12,ncol=10,dimnames=list(c(1:24),c(1:10)))
作为输入的日期(文本文件)myDates:
1981 1981,02 1981,03 1981,04 1981, 05 1981年,06 1981年,1981年1981年,1981年,1981年,1981年,1981年, 11 1981年,12 1981年,01 1982年,02年1982年,03年1982年,04年,1982年, 05 1982年,06 1982年,1982年,1982年,1982年,1982年,1982年,1982年, 1982年12月,1982年12月等
Time_step_hist来自包含以这种格式超过2年的日期的文本文件:
19810101,19810102,19810103,19810104,19810105等
然后一个for循环为我做的工作:
for (i in 1:10) {
# loop over dates and acquire date
Prec_hist = read.table(paste(P_read_table_hist$V1[i]), header=F)
# then put date and rain together
data_Prec_Hist <- data.frame(Time_step_hist[1:7305,], Prec_hist[1:7305,])
# call function to get and write to matrix
pmatrix_hist <- WriteRainyDaysCountToMatrix(data_Prec_Hist, Dates_hist, pmatrix_hist, i)
}
我不知道如何输入我使用过的雨数据,但可以使用0和1的简单列表。
在矩阵中只存储了天数,第二个矩阵用于存储连续几天的降雨量。
最大的性能提升在哪里?
非常感谢提前!
答案 0 :(得分:0)
欢迎! 你的直觉是正确的,这种操作应该在几秒钟而不是几小时内测量。
你最大的收获来自最小化循环和使用矢量化函数。
一个好的起点是使用as.Date将字符串转换为日期,并使用子集来简化循环。
请考虑as.Date('19810101',"%Y%m%d")
将字符串转换为日期,而不是所有那些嵌套循环经过多年和几个月。
以下是修改过的结构可能看起来的样子,我不得不猜测你的“myDataFrame”有一列日期和一列降水值。
set.seed(42)#for repeatability
#Dummy Data
#some dates
dates <- seq(as.Date("19810101","%Y%m%d"), as.Date("19821231","%Y%m%d"), by = "day")
#random Precipitation
precip <- sample(0:3,length(dates), replace = TRUE, prob = c(.7,.1,.1,.1))
myDataFrame<- data.frame(dates,precip)
#
#real code
#
#Create a month Column
myDataFrame$month <- as.numeric(format(myDataFrame$dates,'%m'))
myDataFrame$year <- as.numeric(format(myDataFrame$dates,'%Y'))
#order your data frame by date
myDataFrame[order(as.Date(myDataFrame$dates)),]
#create lists of the months, and years to drive loops later
yr_list <- levels(factor(myDataFrame$year))
mo_list <- levels(factor(myDataFrame$month))
#A smoother loop structure will look like like this, relying on subsetting
for(y in yr_list){
suby <- subset(myDataFrame, myDataFrame[,"year"] == y)
for(m in mo_list){
subm <- subset(suby, suby[,"month"] ==m)
for(d in 1:length(subm)){
#here you can run your count for each month, and then write the record
#to a data structure of your choosing
}
}
}
将来会有所帮助的一些事情:1)输出你的数据源的样子2)显示你想要输出的最小例子。
一些提示一般提示:将您引入脚本的日期子集可以帮助您更快地进行迭代,并查找system.time()和proc.time()以测量您的代码,以查看您所做的改进。 / p>