在Julia分组DataFrame中按组检测列是否存在指定值
Julia DataFramesMeta 实现分组判断并新增列
原始数据与需求
首先定义初始DataFrame:
using DataFrames, DataFramesMeta df = DataFrame(x = [1, 2, 3, 4, 5, 6], y = ["a", "a", "a", "b", "b", "b"])
需求:新增列z,按y列分组后,判断每组中是否存在x == 2的行,最终结果如下:
6×3 DataFrame Row │ x y z │ Int64 String Bool ─────┼────────────────────── 1 │ 1 a true 2 │ 2 a true 3 │ 3 a true 4 │ 4 b false 5 │ 5 b false 6 │ 6 b false
尝试过的方法及问题
直接使用
@transform分组处理:@transform(groupby(df, :y), :z = :x == 2 ? true : false)以及单独使用
@rtransform均未达到预期——这类写法会逐行判断x == 2,而非针对整个组做统一判断。尝试结合Impute包填充:
using Impute df_new = @chain df begin @rtransform :z = :x == 2 ? 1 : missing groupby(_, :y) @transform :z_new = Impute.locf(:z) end触发错误
AssertionError: !(all(ismissing, data)),原因是b组的z列全为missing,不满足Impute.locf的非全缺失要求。临时可行方案:
df_new = @chain df begin @rtransform :z = :x == 2 ? true : false groupby(_, :y) @transform :z = sum(:z) .> 0 ? true : false end该方案通过统计组内
true的数量判断是否存在目标行,但语义不够直观。
更优解决方案
利用any函数直接判断组内是否存在满足条件的元素,结合@chain和分组操作,写法简洁且语义准确:
df_new = @chain df begin groupby(_, :y) @transform :z = any(:x .== 2) end
原理:分组后,any(:x .== 2)会对当前组的x列整体判断是否存在等于2的元素,返回一个布尔值,随后该值会自动广播到组内所有行,完美匹配需求。
内容的提问来源于stack exchange,提问作者Pascal
相关产品推荐
相关产品推荐

