我正在编写一个获取2矩阵乘积的函数。
transpose' :: [[a]] -> [[a]]
transpose' [[]] = []
transpose' m = (map head m) : transpose' (map tail m)
dotProduct :: [Int] -> [Int] -> Int
dotProduct [] [] = 0
dotProduct (x:xs) (y:ys) = (x*y) + dotProduct xs ys
matrixProduct :: [[Int]] -> [[Int]] -> [[Int]]
matrixProduct [] _ = []
matrixProduct (x:xs) y = (map (dotProduct x) (transpose' y)):matrixProduct xs y
我总是得到类似[[2,2, ***Exception: Prelude.head empty List
是因为我的函数有错误的基本情况吗?
我不确定应该是什么。
答案 0 :(得分:3)
我修复了我在解决方案中发现的问题,这就是我得到的:
transpose :: [[a]] -> [[a]]
transpose [] = repeat []
transpose (m:ms) = zipWith (:) m (transpose ms)
dotProduct :: [Int] -> [Int] -> Int
dotProduct xs ys = sum $ zipWith (*) xs ys
matrixProduct :: [[Int]] -> [[Int]] -> [[Int]]
matrixProduct xs ys = [ [dotProduct x y | y <- transpose ys ] | x <- xs ]
你可以看到这应该非常接近矩阵乘法的row * col
定义(表示中矩阵的行只是外部列表的元素,列是元素的转置矩阵外部列表)
除此之外,我简化了你的dotProduct
(但你的很好)和
修复了你的transpose'
- 顺便说一下,这是你错误的来源!
我认为基本的想法是正确的,但你遇到了基本情况([]
而不是[[]]
)以及你应该将第一行映射到转置休息的方式的问题 - 同时注意您可以使用repeat []
为[]
提供zipWith
的无限列表,因为[]
会很好地处理它 - 如果您使用zipWith (:) m [] == []
而不是您的递归案例会在[]
并冒泡到transpose
我的m
与您的head
有点不同而且可能很复杂 - 您的问题是tail
内的一个或多个列表可能为空,这会导致transpose' :: [[a]] -> [[a]]
transpose' m
| and (map (not . null) m) = (map head m) : transpose' (map tail m)
| otherwise = []
和{{ 1}}失败 - 所以你必须保护这个案子:
map (not . null) m
result: [bool]
会检查每一行是否为非空(and (map (not . null) m)
)df['values'].apply(lambda x: pd.Series(x))
断言所有行都是非空的