获取 Haskell CSV 中的列并推断列类型

2024-01-12

我正在交互式 ghci 会话中探索 csv 文件(在 jupyter 笔记本中):

import Text.CSV
import Data.List
import Data.Maybe

dat <- parseCSVFromFile "/home/user/data.csv"
headers = head dat
records = tail dat

-- define a way to get a particular row by index
indexRow :: [[Field]] -> Int -> [Field]
indexRow csv index = csv !! index

indexRow records 1
-- this works! 

-- Now, define a way to get a particular column by index
indexField :: [[Field]] -> Int -> [Field]
indexField records index = map (\x -> x !! index) records

如果我事先知道第 3 列的类型,则此方法有效:

map (\x -> read x :: Double) $ indexField records 3

我怎样才能问read例如,当我的列可能包含字符串或数字时,推断类型可能是什么?我想为我尝试一下,但是:

map read $ indexField records 3

失败了

Prelude.read: no parse

我不在乎它们是字符串还是数字,我只需要它们都是相同的,并且我无法找到一种至少使用读取函数来指定的方法。

奇怪的是,如果我像这样定义一个均值函数:

mean :: Fractional a => [a] -> Maybe a
mean [] = Nothing
mean [x] = Just x
mean xs = Just (sum(xs) / (fromIntegral (length xs)))

这有效:

mean $ map read $ indexField records 2
Just 13.501359655240003

但如果没有平均值,这仍然失败:

map read $ indexField records 2
Prelude.read: no parse

很遗憾,read遇到这样的情况,已经束手无策了。让我们回顾一下read:

read :: Read a => String -> a

如你看到的,a不依赖于输入,而仅依赖于输出,因此也依赖于我们函数的上下文。如果你使用read a + read b,那么额外的Num上下文会将类型限制为Integer or Double due to default规则。让我们看看它的实际效果:

> :set +t
> read "1234"
*** Exception: Prelude.read: no parse
> read "1234" + read "1234"
2468
it :: (Num a, Read a) => a

Ok, a仍然没有帮助。是否有任何类型我们可以在没有额外上下文的情况下阅读?当然,单位:

> read "()"
()
it :: Read a => a

这仍然没有任何帮助,所以让我们启用单态限制 https://stackoverflow.com/q/32496864/1139697:

> :set -XMonomorphismRestriction
> read "1234" + read "1234"
2468
it :: Integer

啊哈。最后,我们有一个Integer。由于+,我们必须决定一种类型。现在,随着MonomorphismRestriction启用后会发生什么read "1234"没有额外的上下文?

> read "1234"
<interactive>:20:1
   No instance for (Read a0) arising from a use of 'read'
   The type variable 'a0' is ambiguous

现在 GHCi 不选择任何(默认)类型和力量you选择一个。这使得潜在的错误更加清晰。

那么我们该如何解决这个问题呢?由于 CSV 可以在运行时包含任意字段,并且所有类型都是静态确定的,因此我们必须通过引入类似的内容来作弊

data CSVField = CSVString String | CSVNumber Double | CSVUnknown

然后写

parse :: Field -> CSVField

毕竟我们的类型需要覆盖all可能的字段。

但是,对于您的情况,我们可以限制read's type:

myRead :: String -> Double
myRead = read

但这并不明智,因为如果该列不包含,我们仍然可能会遇到错误Double首先。所以,让我们使用readMaybe and mapM:

columnAsNumbers :: [Field] -> Maybe [Double]
columnAsNumbers = mapM readMaybe

这样,类型就固定了,我们被迫检查是否有Just某事或Nothing:

mean <$> columnAsNumbers (indexFields records 2)

如果您发现自己经常使用columnAsNumbers不过,创建一个运算符:

(!!$) :: [[Field]] -> Maybe [Double]
records !!$ index = columnAsNumbers $ indexFields records index
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

获取 Haskell CSV 中的列并推断列类型 的相关文章

随机推荐

  • 如何在Android的不同应用程序中使用广播接收器?

    我在 Eclipse 的两个不同项目中有两个应用程序 一个应用程序 A 定义首先启动的活动 A1 然后我从这个活动开始第二个项目 B 中的第二个活动 B1 这很好用 我通过以下方式启动它 Intent intent new Intent p
  • 使用 Android Nougat 打开图库中的图像

    我想在 Android Nougat 上打开图库中保存的图像 但我得到的是一个黑色的图库页面 并显示消息 无法加载照片 这是我的代码 Manifest
  • 未捕获的引用错误:纬度未定义[重复]

    这个问题在这里已经有答案了 可能的重复 JavaScript 变量作用域 https stackoverflow com questions 500431 javascript variable scope 我的脚本有问题 我想从 pos
  • 优雅地退出node.js

    我正在阅读这本优秀的在线书籍http nodebeginner org http nodebeginner org 并尝试简单的代码 var http require http function onRequest request resp
  • 如何从Python调用scala?

    我想在 Scala 中构建我的项目 然后在 Python 脚本中使用它来进行数据黑客攻击 作为模块或类似的东西 我已经看到有多种方法可以使用 Jython 将 python 代码集成到 JVM 语言中 尽管只有 Python 2 项目 但我
  • 想要使用 ActionSherlockBar 添加选项卡

    我想用 ActionSherlockBar 添加选项卡所以我使用了一些代码 资源 https stackoverflow com questions 13640512 android actionbar sherlock with tabs
  • Graphviz 未在 jupyter 笔记本 python = 3.6 中运行?

    我正在尝试运行 graphviz 以查看 jupyter 笔记本上的点文件 其中已导入 dot exe 路径的路径 G anaconda3 envs tensorflowgpu Library bin graphviz G anaconda
  • 将数据帧随机分成 n 个相等的部分

    假设我有一个不同行数的数据帧列表 AB df data frame replicate 2 sample 0 130 201 rep TRUE BC df data frame replicate 2 sample 0 130 200 re
  • ASP.NET 路由是否可用于为 .ashx (IHttpHander) 处理程序创建“干净”的 URL?

    我有一些使用普通旧式的 REST 服务IHttpHandlers 我想生成更清晰的 URL 这样路径中就没有 ashx 有没有办法使用 ASP NET 路由来创建映射到 ashx 处理程序的路由 我以前见过这些类型的路线 Route to
  • 如何在sql中选择连续日期

    是否有任何函数可以检查连续日期 我在处理以下问题时遇到问题 我的桌子上有一个datetime包含以下数据的列 2015 03 11 2015 03 12 2015 03 13 2015 03 16 指定开始日期为2015 3 11和结束日期
  • FireBase API 是否有未缩小的 JavaScript 版本?

    我正在为通过 FireBase 提供 API 的设备开发一个界面 但我没有使用 Java JavaScript 或 FireBase 提供的库的任何其他语言 我正在使用 Lua 虽然我可以轻松实现 REST API 但我希望能够使用 Fir
  • Google APIs Explorer 未从我的应用程序引擎应用程序中找到可用的 ApiMethod

    我有一个可以正常编译的 App Engine 应用程序 我使用本地主机上的 Google Apis Explorer 测试方法调用 https developers google com apis explorer base http lo
  • 临时表在同一连接池上的多个请求中是否唯一?

    我有以下存储过程 它使用临时表批量导入数据 我知道临时表对于每个会话都是唯一的 但是我想知道我的应用程序是否使用线程并向存储过程发出多个并发请求 使用应用程序池中的相同 sql 连接 它们最终会引用相同的临时表吗 CREATE PROCED
  • Rhino - 将 javascript 对象传递给 java

    我对 Rhino 很陌生 我的问题是如何实现以下目标 假设我有一个 javascript 对象 它遵循如下所示的内容 我可以在 java 中使用它 var myObject new Object myObject string1 Hello
  • 没有jquery的自定义滚动条

    我正在寻找一个无需 jquery 即可工作的自定义滚动条 我不能使用 jquery 因为其他东西也是无 jquery 的 并且它针对快速加载进行了优化 将不胜感激与我分享的任何想法 NONNNNN 如果您不想使用 jQuery 您可以随时尝
  • 正则表达式正在抓取前面的字符

    所以我在正则表达式中遇到了一些不一致的行为 我的正则表达式 lt test 输入字符串 test exe c echo teststring gt test teststring 当我运行这个时https Regex101 com http
  • 自 UTC 时区当天开始以来的秒数

    如何在Python中找到 自UTC时区开始以来的秒数 我查看了文档 但不明白如何使用它datetime timedelta 这是一种方法 from datetime import datetime time utcnow datetime
  • 设置selectedindex不触发onchange事件

    我正在尝试更改选择标签的选定索引 但是通过 jquery 更改索引时不会触发 onchange 事件 我正在动态地为选择标签创建选项 我不会知道选项标签的值 还有其他方法可以实现吗 这是我的代码片段 请随意提供意见 function cal
  • 如何让 Pyflakes 忽略语句?

    我们的许多模块都是从以下开始的 try import json except ImportError from django utils import simplejson as json Python 2 4 fallback 这是整个文
  • 获取 Haskell CSV 中的列并推断列类型

    我正在交互式 ghci 会话中探索 csv 文件 在 jupyter 笔记本中 import Text CSV import Data List import Data Maybe dat lt parseCSVFromFile home