pt2*_*121 2 python haskell functional-programming scala numpy
我是一个功能性编程新手.我想知道如何在python,scala或haskell中实现numpy.where().一个好的解释对我有帮助.
在Haskell中,对于n维列表来说,就像NumPy等效支持一样,需要一个相当高级的类型类构造,但是1维案例很容易:
select :: [Bool] -> [a] -> [a] -> [a]
select [] [] [] = []
select (True:bs) (x:xs) (_:ys) = x : select bs xs ys
select (False:bs) (_:xs) (y:ys) = y : select bs xs ys
Run Code Online (Sandbox Code Playgroud)
这只是一个简单的递归过程,依次检查每个列表的每个元素,并在每个列表到达结尾时生成空列表.(请注意,这些是列表,而不是数组.)
这是一个更简单但不太明显的一维列表实现,翻译NumPy文档中的定义(信用到joaquin指出):
select :: [Bool] -> [a] -> [a] -> [a]
select bs xs ys = zipWith3 select' bs xs ys
where select' True x _ = x
select' False _ y = y
Run Code Online (Sandbox Code Playgroud)
为了实现两参数的情况(返回条件为True的所有索引;归功于Rex Kerr指出这种情况),可以使用列表推导:
trueIndices :: [Bool] -> [Int]
trueIndices bs = [i | (i,True) <- zip [0..] bs]
Run Code Online (Sandbox Code Playgroud)
它也可以用现有的方式编写select,尽管没有多大意义:
trueIndices :: [Bool] -> [Int]
trueIndices bs = catMaybes $ select bs (map Just [0..]) (repeat Nothing)
Run Code Online (Sandbox Code Playgroud)
这是n维列表的三参数版本:
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
class Select bs as where
select :: bs -> as -> as -> as
instance Select Bool a where
select True x _ = x
select False _ y = y
instance (Select bs as) => Select [bs] [as] where
select = zipWith3 select
Run Code Online (Sandbox Code Playgroud)
这是一个例子:
GHCi> select [[True, False], [False, True]] [[0,1],[2,3]] [[4,5],[6,7]]
[[0,5],[6,3]]
Run Code Online (Sandbox Code Playgroud)
但是,您可能希望在实践中使用正确的n维数组类型.如果你只是想select在一个特定的n的n维列表上使用,luqui的建议(来自这个答案的评论)是可取的:
在实践中,我会使用
(zipWith3.zipWith3.zipWith3) select' bs xs ys(对于三维情况)而不是类型类黑客.
(添加的多种组合物zipWith3作为ñ增加.)
在python中numpy.where.__doc__:
If `x` and `y` are given and input arrays are 1-D, `where` is
equivalent to::
[xv if c else yv for (c,xv,yv) in zip(condition,x,y)]
Run Code Online (Sandbox Code Playgroud)