我是一名功能性编程新手。 我想知道如何在python,scala或haskell中实现numpy.where()。 一个好的解释对我有帮助。
答案 0 :(得分:6)
在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
这只是一个简单的递归过程,依次检查每个列表的每个元素,并在每个列表到达结尾时生成空列表。 (请注意,这些是列表,而不是数组。)
这是一个更简单但不太明显的一维列表实现,翻译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
要实现两参数的情况(返回条件为True的所有索引;归功于Rex Kerr指出这种情况),可以使用列表推导:
trueIndices :: [Bool] -> [Int]
trueIndices bs = [i | (i,True) <- zip [0..] bs]
它也可以用现有的select
编写,虽然没有多大意义:
trueIndices :: [Bool] -> [Int]
trueIndices bs = catMaybes $ select bs (map Just [0..]) (repeat Nothing)
这是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
以下是一个例子:
GHCi> select [[True, False], [False, True]] [[0,1],[2,3]] [[4,5],[6,7]]
[[0,5],[6,3]]
但是,您可能希望在实践中使用正确的n维数组类型。如果你只想在一个特定的 n 的n维列表中使用select
,那么luqui的建议(来自这个答案的评论)是可取的:
在实践中,我会使用
(zipWith3.zipWith3.zipWith3) select' bs xs ys
(对于三维情况)而不是类型类黑客。
(添加更多zipWith3
n 的成分会增加。)
答案 1 :(得分:5)
来自numpy.where.__doc__
的python:
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)]
答案 2 :(得分:3)
有两个用例在哪里;在一种情况下,你有两个数组,而在另一种情况下,你只有一个。
在两项案例numpy.where(cond)
中,您将获得条件数组为true的索引列表。在Scala中,您通常会
(cond, cond.indices).zipped.filter((c,_) => c)._2
显然不那么紧凑,但这不是人们通常在Scala中使用的基本操作(例如,构建块不同,不再强调索引)。
在三项内容numpy.where(cond,x,y)
中,您可以获得x
或y
,具体取决于cond
是真(x
)还是假( y
)。在Scala中,
(cond, x, y).zipped.map((c,tx,ty) => if (c) tx else ty)
执行相同的操作(再次不那么紧凑,但同样,通常不是基本操作)。请注意,在Scala中,您可以更轻松地将cond
作为测试x
和y
并生成true或false的方法,然后您将
(x, y).zipped.map((tx,ty) => if (c(tx,ty)) tx else ty)
(尽管通常即使简短,您也可以将数组命名为xs
和ys
以及各个元素x
和y
。)