使用sparklyr处理数据时提取数字转numeric出现NaN的问题求助
解决sparklyr处理分布式数据框提取字符串并计算的问题
嘿,我明白你遇到的麻烦了——用sparklyr处理懒查询对象的时候,直接用本地R的stringi函数肯定不行,因为Spark的分布式数据没法直接调用本地函数执行,这就是你之前得到NaN或者报错的根本原因。咱们换用Spark原生的字符串处理函数来解决这个问题,具体步骤如下:
核心思路
你的csj是tbl_spark(懒查询对象),所有操作都要能被推送到Spark集群执行,所以必须用Spark支持的函数,而不是本地R包的函数。我们可以用Spark的正则提取或者字符串分割来拿到两个数字,再做计算。
方法一:正则表达式提取
这是最直接的方式,用Spark的regexp_extract函数捕获字符串里的两个数字:
library(sparklyr) library(dplyr) csj_processed <- csj %>% # 提取[后面的第一个数字(捕获组1) mutate(col1 = regexp_extract(helpful, "\\[(\\d+),", 1)) %>% # 提取,和]之间的第二个数字(捕获组1) mutate(col2 = regexp_extract(helpful, ",(\\d+)\\]", 1)) %>% # 把提取到的字符串转成数值类型 mutate(col1 = as.numeric(col1), col2 = as.numeric(col2)) %>% # 处理第二个数字为0的情况,替换成1 mutate(col2 = ifelse(col2 == 0, 1, col2)) %>% # 计算目标help列 mutate(help = col1 / col2)
方法二:字符串分割法
如果你的helpful列格式很规整,也可以先去掉括号,再按逗号分割成数组,提取元素:
csj_processed <- csj %>% # 去掉字符串里的[和] mutate(helpful_clean = regexp_replace(helpful, "\\[|\\]", "")) %>% # 按逗号分割成数组 mutate(helpful_split = split(helpful_clean, ",")) %>% # 提取数组的第1和第2个元素(Spark数组索引从1开始),转成数值 mutate(col1 = as.numeric(element_at(helpful_split, 1)), col2 = as.numeric(element_at(helpful_split, 2))) %>% # 替换0为1 mutate(col2 = ifelse(col2 == 0, 1, col2)) %>% # 计算help列 mutate(help = col1 / col2) %>% # 可选:删除中间生成的临时列 select(-helpful_clean, -helpful_split)
为啥之前的方法不行?
- 用
stringi函数:stringi是本地R包的函数,没法在Spark集群上执行,所以处理分布式的tbl_spark时,会返回NaN或者空值。 - 报错找不到
helpful:当你直接用helpful但没搭配Spark兼容的函数时,dplyr没法正确识别分布式数据框的列,就会报错。 - 去掉
as.numeric:提取出来的是字符串类型,直接做除法会失败,所以得到空值。
额外注意
如果你的helpful列里有空格(比如[ 0 , 5 ]),记得调整正则表达式,比如把"\\[(\\d+),"改成"\\[(\\d+),\\s*",或者分割的时候处理空格,保证能正确提取数字。
最后,因为是懒查询,你需要用collect(csj_processed)或者compute(csj_processed)来触发计算,查看最终结果哦。
内容的提问来源于stack exchange,提问作者Alice Shin
相关产品推荐
相关产品推荐

