R语言中针对大数据的离散小波变换实现问题咨询
Hey there! Let's get your discrete wavelet transform (DWT) implementation sorted for your matrix data in R. I see you've started building the createWt function—let's fill in the missing pieces and even add some optimizations for better performance.
First, here's a complete, efficient serial version of your function. We'll pre-allocate the result matrix to avoid slow dynamic binding, and properly extract both approximation and detail coefficients from the dwt output:
library(data.table) library(wavelets) library(parallel) # Serial version of DWT function for matrix input createWt <- function(d_matrix){ # Get the length of coefficients from a sample row to pre-allocate matrix sample_wt <- dwt(d_matrix[1,], filter = "haar", boundary = "periodic") total_coeffs <- length(c(sample_wt@W, sample_wt@V[[1]])) # Initialize result matrix (faster than dynamic rbind) wtScore <- matrix(nrow = nrow(d_matrix), ncol = total_coeffs) # Process each row for (i in 1:nrow(d_matrix)){ row_data <- d_matrix[i,] wt_result <- dwt(row_data, filter = "haar", boundary = "periodic") # Combine approximation (W) and detail (V1) coefficients wtScore[i,] <- c(wt_result@W, wt_result@V[[1]]) } # Add meaningful column names for clarity colnames(wtScore) <- c( paste0("approx_", seq_along(sample_wt@W)), paste0("detail_", seq_along(sample_wt@V[[1]])) ) return(wtScore) }
Since you loaded the parallel package, let's leverage it to speed up processing if you have a large number of rows. This cuts down runtime by distributing work across multiple CPU cores:
For Linux/macOS (uses mclapply):
# Parallel DWT function (Linux/macOS) createWt_parallel <- function(d_matrix, num_cores = detectCores() - 1){ # Helper function to process a single row process_single_row <- function(row){ wt <- dwt(row, filter = "haar", boundary = "periodic") c(wt@W, wt@V[[1]]) } # Get sample coefficient length for column naming sample_coeffs <- process_single_row(d_matrix[1,]) # Process rows in parallel wt_coeff_list <- mclapply( 1:nrow(d_matrix), function(i) process_single_row(d_matrix[i,]), mc.cores = num_cores ) # Convert list of coefficients to a matrix wtScore <- do.call(rbind, wt_coeff_list) # Name columns colnames(wtScore) <- c( paste0("approx_", seq_along(sample_coeffs)[1:(length(sample_coeffs)/2)]), paste0("detail_", seq_along(sample_coeffs)[(length(sample_coeffs)/2 + 1):length(sample_coeffs)]) ) return(wtScore) }
For Windows (uses parLapply since mclapply isn't supported):
# Parallel DWT function (Windows) createWt_parallel_win <- function(d_matrix, num_cores = detectCores() - 1){ # Create parallel cluster cl <- makeCluster(num_cores) # Export required functions and load packages on cluster nodes clusterExport(cl, "dwt") clusterEvalQ(cl, library(wavelets)) # Helper function for row processing process_single_row <- function(row){ wt <- dwt(row, filter = "haar", boundary = "periodic") c(wt@W, wt@V[[1]]) } # Get sample coefficients sample_coeffs <- process_single_row(d_matrix[1,]) # Process rows in parallel wt_coeff_list <- parLapply( cl, 1:nrow(d_matrix), function(i) process_single_row(d_matrix[i,]) ) # Clean up cluster stopCluster(cl) # Convert to matrix and name columns wtScore <- do.call(rbind, wt_coeff_list) colnames(wtScore) <- c( paste0("approx_", seq_along(sample_coeffs)[1:(length(sample_coeffs)/2)]), paste0("detail_", seq_along(sample_coeffs)[(length(sample_coeffs)/2 + 1):length(sample_coeffs)]) ) return(wtScore) }
- Data Prep: Ensure your matrix is numeric (use
as.numeric()if needed) since DWT only works with numerical data. Converting yourdata.tableto a matrix is straightforward withas.matrix(your_data_table). - Boundary Handling: You're using
boundary = "periodic"which works great for cyclic data. If your data is non-periodic, consider switching to"reflection"or"zero"depending on your use case. - Filter Selection: You're using the Haar filter—if you need smoother coefficients, experiment with other filters like
"d4"or"sym8"(checkwavelets::filter.select()for options).
内容的提问来源于stack exchange,提问作者ML_Passion

