按列的内容对 Maple 数据框进行排序

Sorting a Maple dataframe by the contents of a column

我有一个存储在 Maple 数据框中的数据集,我想按给定列中的值对其进行排序。我的例子更大,但数据是这样的,我有两列数据,一列有一些数值,另一列有字符串。因此,例如,假设我有一个构造为:

的数据框
Mydata := DataFrame(<<2,1,3,0>|<"Red","Blue","Green","Orange">>, columns = [Value,Color] );

我想要类似 sort 命令的东西能够 return 相同的数据帧,其中 Value 列中的数字按升序或降序排序,但 sort 命令似乎不支持数据框。关于如何对此进行排序的任何想法?

你是对的,sort command doesn't currently support DataFrames (but it should!). I've gotten around this by converting DataFrame 列(一个 DataSeries)到 Vector,使用 output = permutation 选项对 Vector 进行排序,然后根据结果索引 DataFrame。使用您的示例:

Mydata := DataFrame(<<2,1,3,0>|<"Red","Blue","Green","Orange">>, columns = [Value,Color] );
sort( convert( Mydata[Value], Vector ), output = permutation );

哪个 returns:

    [4, 2, 1, 3]

按此结果索引原始 DataFrame,然后 return按 Value 列的升序排列排序后的 DataFrame:

Mydata[ sort( convert( Mydata[Value], Vector ), output = permutation ), .. ];
Mydata[ [4, 2, 1, 3], .. ];

returns:

        [     Value     Color  ]
        [                      ]
        [4      0      "Orange"]
        [                      ]
        [2      1       "Blue" ]
        [                      ]
        [1      2       "Red"  ]
        [                      ]
        [3      3      "Green" ]

也就是说,我需要多次对 DataFrame 进行排序,因此我还创建了一个似乎适用于我的大多数数据集的过程。此过程使用与使用 sort 命令类似的方法,但是它不需要任何数据转换,因为它适用于 Maple DataFrame 对象本身。为此,我需要设置 kernelopts(opaquemodules = false) 以便直接使用内部 DataFrame 数据对象(您也可以对中间矩阵和向量进行大量转换,但这种方法限制了重复内部数据的数量创建):

DSort := proc( self::{DataFrame,DataSeries}, {ByColumn := NULL} )
    local i, opacity, orderindex;
    opacity := kernelopts('opaquemodules' = false):
    if type( self, ':-DataFrame' ) and ByColumn <> NULL then
        orderindex := sort( self[ByColumn]:-data, ':-output' = ':-permutation', _rest );
    elif type( self, ':-DataSeries' ) and ByColumn = NULL then
        orderindex := sort( self:-data, ':-output' = ':-permutation', _rest );
    else
        return self;
    end if;
    kernelopts(opaquemodules = opacity): #Set opaquemodules back to original setting
    if type( self, ':-DataFrame' ) then
        return DataFrame( self[ orderindex, .. ] );
    else
        return DataSeries( self[ orderindex ] );
    end if;
end proc:

例如:

DSort( Mydata, ByColumn=Value ); 

returns:

        [     Value     Color  ]
        [                      ]
        [4      0      "Orange"]
        [                      ]
        [2      1       "Blue" ]
        [                      ]
        [1      2       "Red"  ]
        [                      ]
        [3      3      "Green" ]

这对字符串也有效,所以 DSort( Mydata, ByColumn=Color ); 应该有效。

        [     Value     Color  ]
        [                      ]
        [2      1       "Blue" ]
        [                      ]
        [3      3      "Green" ]
        [                      ]
        [4      0      "Orange"]
        [                      ]
        [1      2       "Red"  ]

在此过程中,我向 sort 命令传递了额外的参数,这意味着您还可以添加升序或降序选项,因此您可以执行 DSort( Mydata, ByColumn=Value, `>` ); 到 return DataFrame 以 'Value' 降序排列(尽管这似乎不太适合字符串)。