如何用最后一个元素haskell划分2d列表?

时间:2016-03-15 15:43:22

标签: list haskell

我正在尝试根据Haskell中每个列表中的最后一个元素将列表分组到2dlist中。像这样:

[[0,1],[2,2],[0,2],[1,1]]

会像这样成为一个3D列表:

[[[0,1],[1,1]],[[0,2],[2,2]]]

或使用任何数据结构将数据分成n个类别。

具体来说,我正在尝试在本教程中实现seperateByClass方法http://machinelearningmastery.com/naive-bayes-classifier-scratch-python/

2 个答案:

答案 0 :(得分:1)

目标是转换

def separateByClass(dataset):
    separated = {}
    for i in range(len(dataset)):
        vector = dataset[i]
        if (vector[-1] not in separated):
            separated[vector[-1]] = []
        separated[vector[-1]].append(vector)
    return separated


dataset = [[1,20,1], [2,21,0], [3,22,1]]
separated = separateByClass(dataset)
print('Separated instances: {0}').format(separated)

有输出

Separated instances: {0: [[2, 21, 0]], 1: [[1, 20, 1], [3, 22, 1]]}

到Haskell。这是Data.Map的{​​{1}}的完美用例,其中列出了键值对以及当两对碰巧共享相同键时组合值的策略。

fromListWith :: Ord k => (a -> a -> a) -> [(k, a)] -> Map k a

干得好,哈斯克尔。

答案 1 :(得分:1)

import Data.List(groupBy, sortBy)
import Data.Ord(compare)

groupBy (\x y -> x!!1==y!!1) $ sortBy (\x y -> compare (x!!1) (y!!1)) [[0,1],[2,2],[0,2],[1,1]]
[[[0,1],[1,1]],[[2,2],[0,2]]]

或,将索引访问权限更改为最后一次

groupBy (\x y -> last x==last y) $ sortBy (\x y -> compare (last x) (last y)) [[0,1],[2,2],[0,2],[1,1]]
[[[0,1],[1,1]],[[2,2],[0,2]]]

使用一些辅助函数可能更容易

compareLast x y = compare (last x) (last y)
equalLast x y =  EQ == compareLast x y

groupBy equalLast $ sortBy compareLast [[0,1],[2,2],[0,2],[1,1]]
[[[0,1],[1,1]],[[2,2],[0,2]]]

或者,更进一步

compareBy f x y = compare (f x) (f y)
equalBy f = ((EQ ==) .) . compareBy f
partitionBy f = groupBy (equalBy f) . sortBy (compareBy f)

partitionBy last [[0,1],[2,2],[0,2],[1,1]]
[[[0,1],[1,1]],[[2,2],[0,2]]]