如何在`DataFrames.jl`中的分组数据框的子表中插入列?

问题描述 投票:0回答:1

我想做的是:

  • DataFrames.jl
    中按列(“col1”)对数据框进行分组,称之为
    grouped_df

  • 将子表从

    grouped_df
    发送到用户定义的函数

    • 用户定义的函数将转换现有列,并应添加包含相关数据的新列

我想在同一函数中转换旧列并添加新列,因为这两个操作都依赖于基本相同的计算,但记录方式略有不同。

function apply_scan_difference(df::AbstractDataFrame,ref_scan::Float64)
    
    current_scan::Float64 = calculate_current_scan(df)
    
    scan_difference::Float64 = current_scan - ref_scan
    
    df.scan = df.scan .- scan_difference

    insertcols!(df, ncol(df)+1, :shift .= scan_difference ) # `scan_difference` has already been calculated and being able to record it here would be efficient,right`
    
    return df::AbstractDataFrame
end

如您所见,

scan_difference
是为每个组计算的,并应用于旧列
scan
,但我也想为每个组记录它。从心理上来说,感觉能够在同一个函数中执行此操作将是更有效的方法。

但是当我

combine(sdf -> apply_scan_different(sdf, ref_scan), grouped_df)
时,我收到此错误:
MethodError: no method matching ndims(::Type{Symbol})

我尝试将功能更改为

function apply_scan_difference(df::AbstractDataFrame,ref_scan::Float64)
    
    current_scan::Float64 = calculate_current_scan(df)
    
    scan_difference::Float64 = current_scan - ref_scan
    
    df.scan = df.scan .- scan_difference

    insertcols!(df, ncol(df)+1, :shift => fill(scan_difference, nrow(df))) # `scan_difference` has already been calculated and being able to record it here would be efficient,right`
    
    return df::AbstractDataFrame
end

并将该函数称为

transform(sdf -> apply_scan_different(sdf, ref_scan), grouped_df)
但这会产生此错误

ArgumentError: Column shift is already present in the data frame which is not allowed when 
makeunique=true
 
并且仅将新列数据应用于一组(看起来像第一组)。

我不完全理解设置 makeunique=false` 的含义。

在 Julia 中执行此操作的正确方法是什么?

DataFrames.jl
还是这违背了原则并且不可取?

julia dataframes.jl
1个回答
0
投票

groupby
生成的组仅仅是原始 DataFrame 的视图。如果向其中添加一列,则必然向整个 DataFrame 添加一列。然后,当它尝试将
insertcols
插入到已有它的 DataFrame 中时,
:shift
会出错(因为 默认情况下有
makeunique=false
)。

要解决此问题,您可以复制

sdf

 以便更改不会传播到父 DataFrame,或者先插入一个空 
:shift
 列,然后使用 
sdf[:, :shift] .= scan_difference
 进行指定。

© www.soinside.com 2019 - 2024. All rights reserved.