Я новичок в функциональном программировании. Я хотел бы знать, как реализовать numpy.where() в python, scala или haskell. Хорошее объяснение было бы полезно для меня.Как реализовать «где» (numpy.where (...))?
ответ
В Haskell, делая это для п-мерных списков, как эквивалентные опоры 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
Это только простой рекурсивного процедура, каждый раз проверяя каждый элемент каждого списка и создавая пустой список, когда каждый список достигает своего конца. (Обратите внимание, что эти списки, а не массивы.)
Вот более простой, но менее очевидно, реализация для 1-мерных списков, переводя определение в документации NumPy (кредит Хоакин для указания его):
select :: [Bool] -> [a] -> [a] -> [a]
select bs xs ys = zipWith3 select' bs xs ys
where select' True x _ = x
select' False _ y = y
для достижения дела с двумя аргументов (возвращая все индексы, когда условие истинно; кредитного Рекс Керр для расшивки этого случая из), списка понимание может быть использовано:
trueIndices :: [Bool] -> [Int]
trueIndices bs = [i | (i,True) <- zip [0..] bs]
Это также может быть написано с существующие select
, al хотя нет особого смысла:
trueIndices :: [Bool] -> [Int]
trueIndices bs = catMaybes $ select bs (map Just [0..]) (repeat Nothing)
А вот версия три-аргумент для п-мерных списков:
{-# 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-мерного массива. Если вы просто хотите использовать select
на п-мерный список для одного конкретного п, советы 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)]
Есть два варианта использования для того, где; в одном случае у вас есть два массива, а в другом - только один.
В случае с двумя предметами, numpy.where(cond)
, вы получаете список индексов, в которых выполняется условие-массив. В 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
и производит истинным или ложным, и тогда вы бы
(x, y).zipped.map((tx,ty) => if (c(tx,ty)) tx else ty)
(хотя, как правило, даже если быть кратким вы бы назвать массивы xs
и ys
и отдельные элементы x
и y
).
- 1. как работает numpy.where?
- 2. Где/Как реализовать компаратор
- 3. numpy.where: как отложить оценку параметров?
- 4. Как инвертировать функцию numpy.where (np.where)
- 5. более быстрая альтернатива numpy.where?
- 6. Интерпретация numpy.where results
- 7. Понимание о numpy.where
- 8. вызова `numpy.where` на` masked_array`
- 9. питона: Ошибка с numpy.where
- 10. Фортран эквивалент функции numpy.where()?
- 11. Найти число значений, возвращаемых numpy.where
- 12. Scala: Эквивалент numpy.where() [0]
- 13. несколько условий numpy.where
- 14. питон функция numpy.where для списков
- 15. Как и где это реализовать?
- 16. Как реализовать bubblesort и где
- 17. Где реализовать CLLocationManager
- 18. Где можно «реализовать» проекты?
- 19. Когда/где реализовать FileSystemWatcher
- 20. Векторизованная версия for-loop + numpy.where
- 21. numpy.where для 2+ конкретных значений
- 22. numpy.where() подробное, пошаговое объяснение/примеры
- 23. Где реализовать протоколы Swift?
- 24. Где реализовать блоки catch?
- 25. numpy.where() в градациях серого, неправильные индексы?
- 26. Как реализовать MySQL "где нуль?" В SpringJDBCTemplate
- 27. Как реализовать «где» пункт в Linq
- 28. Понимание времени выполнения numpy.where и эквивалентных альтернатив
- 29. Где я должен реализовать SeekBar.onSeekBarChangeListener?
- 30. iTop, где реализовать onchange javascript?
На практике вместо ручек классных я использую '(zipWith3.zipWith3.zipWith3), выберите 'bs xs ys' (для трехмерного случая). Если я не знаю количество измерений, когда пишу, тогда, как вы сказали, я бы использовал правильный абстрактный тип. – luqui
Да, я полностью. Тем не менее, если вы действительно хотите реализовать 'numpy.where' в Haskell ... Спасибо, что сделали мне, что' zipWith3' будет работать здесь, кстати! Я отредактировал свой ответ соответственно и включил ваш комментарий. :) – ehird
«Полностью согласен» и «заставляя меня осознать», конечно :) – ehird