DataFrames.jl中实现类似R pivot_longer的数组列行展开操作
在Julia中展开DataFrame数组列(类似R的pivot_longer)
给定如下数据集:
Row │ name num_fruits fruits │ String Int64 Array… ─────┼──────────────────────────────────────────────────────── 1 │ Alice 2 ["cherry", "apple"] 2 │ Bob 3 ["grape", "apple", "elderberry"] 3 │ Charlie 5 ["apple", "apple", "elderberry",…
需要将数组列fruits中的每个值转为单独一行,实现类似R中pivot_longer的功能。尝试使用stack函数,但仅生成了值均为字符串"fruits"的列,未达到预期效果。
请问Julia中是否有现成方法实现数据框变长,还是必须使用for循环+append?
期望输出:
10×3 DataFrame Row │ name num_fruits fruit │ String Int64 String ─────┼───────────────────────────────── 1 │ Alice 2 cherry 2 │ Alice 2 apple 3 │ Bob 3 grape 4 │ Bob 3 apple 5 │ Bob 3 elderberry 6 │ Charlie 5 apple 7 │ Charlie 5 apple 8 │ Charlie 5 elderberry 9 │ Charlie 5 cherry 10 │ Charlie 5 apple
数据复现代码:
using Random, DataFrames Random.seed!(0) df = DataFrame(name = ["Alice", "Bob", "Charlie"], num_fruits = [2, 3, 5]) fruits = ["apple", "banana", "cherry", "durian", "elderberry", "fig", "grape"] df[!, :fruits] = [rand(fruits, n) for n in df.num_fruits] stack(df, :fruits) # 尝试的方法
解决方案:使用flatten函数
在Julia的DataFrames包中,flatten函数就是专门用来将数组列的每个元素展开为单独一行的工具,完全符合需求,无需手动编写for循环。
正确代码示例
直接对目标数组列调用flatten:
flatten(df, :fruits)
如果需要将展开后的列名从fruits改为fruit(与期望输出一致),可以在展开后重命名:
flatten(df, :fruits) |> x -> rename(x, :fruits => :fruit)
为什么stack无法实现需求?
stack函数的作用是将多个列转换为"变量-值"的长表结构,而非处理单个列中的数组元素展开。你之前调用stack(df, :fruits)时,它会把fruits列当作一个变量名,因此生成的variable列全为"fruits",value列仍保留原数组,这和你需要的数组元素展开功能完全不同。
输出验证
运行上述flatten代码后,得到的结果与期望输出完全一致:
10×3 DataFrame Row │ name num_fruits fruit │ String Int64 String ─────┼───────────────────────────────── 1 │ Alice 2 cherry 2 │ Alice 2 apple 3 │ Bob 3 grape 4 │ Bob 3 apple 5 │ Bob 3 elderberry 6 │ Charlie 5 apple 7 │ Charlie 5 apple 8 │ Charlie 5 elderberry 9 │ Charlie 5 cherry 10 │ Charlie 5 apple
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

