You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

高效创建数据框新列:提取字符串中的最大值

高效提取字符串中的数值最大值并判断阈值

问题背景

有如下示例数据框:

country <- c('Australia', 'Italy', 'Peru', 'China')
score <- c("0.091", "0.413,.", "-", "0.102,0.102,0.102,.,.,.,.,.,.,.,.")
country_scores <- data.frame(country, score)

score列的每个条目为任意数量的逗号分隔值,或用-表示无数据。需要提取每个字符串中的数值最大值,并判断其是否符合特定阈值。

原使用的tidyverse方案在130万行、186列的数据框上运行极慢(至少8分钟),原代码如下(注:原代码存在笔误,已修正关键错误):

library(tidyverse)

country_scores %>%
  mutate(scores = str_extract_all(score, '\\d+(\\.\\d+)?'), 
         score_max = map_dbl(scores, ~max(as.numeric(.x), na.rm = TRUE)))

高效实现方案

方案1:data.table + stringi(大数据量最优选择)

data.table的列向量化操作结合stringi的快速字符串处理,能大幅降低大数据量下的运算耗时:

library(data.table)
library(stringi)

# 转换为data.table格式
setDT(country_scores)

# 批量处理score列,计算最大值
country_scores[, score_max := {
  # 按逗号分割字符串
  split_list <- stri_split_fixed(score, ",")
  # 遍历每个分割后的列表,转数值并取最大值(忽略NA)
  sapply(split_list, function(x) {
    nums <- as.numeric(x)
    max(nums, na.rm = TRUE)
  })
}]

# 将无数据(score为"-")的结果替换为NA
country_scores[score == "-", score_max := NA_real_]

方案2:Base R向量化优化

无需加载tidyverse,用Base R的向量化函数实现,性能优于原map系列方案:

# 定义单字符串处理函数
get_max_score <- function(s) {
  if (s == "-") return(NA_real_)
  # 分割字符串并转数值
  parts <- strsplit(s, ",")[[1]]
  nums <- as.numeric(parts)
  # 过滤无效值后取最大值
  nums <- nums[!is.na(nums)]
  if (length(nums) == 0) return(NA_real_)
  max(nums)
}

# 向量化应用到整个列
country_scores$score_max <- sapply(country_scores$score, get_max_score)

方案3:优化后的tidyverse实现

如果坚持使用tidyverse,可通过转长格式分组计算减少逐行操作的开销:

library(tidyverse)

country_scores %>%
  # 先标记无数据条目
  mutate(score = ifelse(score == "-", NA_character_, score)) %>%
  # 提取所有数值并展开为长格式
  mutate(scores = str_extract_all(score, '\\d+(\\.\\d+)?')) %>%
  unnest(scores) %>%
  mutate(scores = as.numeric(scores)) %>%
  # 按分组计算最大值
  group_by(country) %>%
  summarise(score_max = max(scores, na.rm = TRUE), .groups = "drop") %>%
  # 合并回原数据框并修正无效值
  right_join(country_scores, by = "country") %>%
  mutate(score_max = ifelse(is.infinite(score_max), NA_real_, score_max))

性能说明

  • data.table + stringi方案性能最优,因为data.table的列操作经过高度优化,stringi的字符串处理速度远快于stringr。
  • 原方案的慢主要源于map_dbl的逐行处理,在百万级行规模下,逐行操作的开销会被急剧放大。

内容的提问来源于stack exchange,提问作者Sky Scraper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 02:55:14