Haskell中CSV两列Float数据拆分为千元素子列表的实现问询
Haskell 导入CSV并拆分列数据
依赖准备
需要在你的项目cabal文件中添加以下依赖:
base >= 4.14 && < 5cassava >= 0.5(用于CSV解析)split >= 0.2(用于列表拆分)
ParserCsv.hs 完整代码
{-# LANGUAGE OverloadedStrings #-} module ParserCsv where import Data.Csv import Data.Vector (Vector) import qualified Data.Vector as V import Data.ByteString.Lazy (ByteString) -- 对应CSV的每行数据:两列Float类型 data CsvRow = CsvRow Float Float deriving (Show) -- 实现无表头CSV的解析逻辑 instance FromRecord CsvRow where parseRecord row = CsvRow <$> row .! 0 <*> row .! 1 -- 解析CSV字节流,返回分离后的两列数据 parseCsv :: ByteString -> Either String ([Float], [Float]) parseCsv bs = case decode NoHeader bs of Left err -> Left err Right rowVector -> let rowList = V.toList rowVector (col1, col2) = unzip $ fmap (\(CsvRow a b) -> (a, b)) rowList in Right (col1, col2)
Main.hs 完整代码
module Main where import ParserCsv import Data.ByteString.Lazy qualified as BL import Data.List.Split (chunksOf) -- 将列表拆分为每个子列表含1000个元素的嵌套列表 splitIntoChunks :: [a] -> [[a]] splitIntoChunks = chunksOf 1000 main :: IO () main = do -- 替换为你的CSV文件路径 csvContent <- BL.readFile "your_data.csv" case parseCsv csvContent of Left err -> putStrLn $ "解析失败: " ++ err Right (dados1, dados2) -> do let dados1Splitted = splitIntoChunks dados1 dados2Splitted = splitIntoChunks dados2 -- 示例输出:打印拆分后的子列表数量 putStrLn $ "第一列拆分后子列表数: " ++ show (length dados1Splitted) putStrLn $ "第二列拆分后子列表数: " ++ show (length dados2Splitted) -- 这里可以添加对dados1Splitted、dados2Splitted的业务处理逻辑
关键说明
- CSV解析:如果你的CSV文件带有表头,只需将
decode NoHeader改为decode HasHeader,并实现FromNamedRecord实例(替换FromRecord)即可。 - 列表拆分:
chunksOf 1000会自动处理剩余元素,32100行数据最终会生成33个子列表(前32个各1000元素,最后1个100元素)。 - 类型匹配:确保CSV中的数据确实是可转换为Float的数值格式,否则解析会返回错误信息。
内容的提问来源于stack exchange,提问作者Diógenes Júnior
相关产品推荐
相关产品推荐

