我正在尝试用 J 中的文件做一些基本的数学运算

I am trying to do some basic math with files in J

我有一个由 space 分隔的数字文件(不是 csv 文件,而是纯文本文件)下面的代码将对出现在连续行中的数字求和。

+/ 0". 1!:1 < F

0".用于将字符串转换为数字) (F为文本文件)

但是如果每个数字都出现在自己的行中,这将不起作用。我该如何修改代码来做到这一点?以及一些针对文件的 J 特定数值分析的通用指针。

考虑:

$ cat nrow
1 2 3 4 5
$ cat ncol
1
2
3
4
5

在 J 中:

   'b' fread 'nrow'
┌─────────┐
│1 2 3 4 5│
└─────────┘
   'b' fread 'ncol'
┌─┬─┬─┬─┬─┐
│1│2│3│4│5│
└─┴─┴─┴─┴─┘
   $".>'b' fread 'ncol'
5
   $".>'b' fread 'nrow'
1 5
   'm' fread 'ncol'
1
2
3
4
5
   'm' fread 'nrow'
1 2 3 4 5
   $".'m' fread 'nrow'
1 5
   $".'m' fread 'ncol'
5

所以它们都可以很直接地用 fread 读入,只是形状有所不同。如果您对文件中特定数字排列的特定文件摄取动词感到满意,则可以到此为止。

但这也可能有用:

   nums =: [: , 0 ". 'm' fread ]
   nums 'nrow'
1 2 3 4 5
   (nums 'nrow') -: nums 'ncol'
1

, (ravel) this just gives you numbers from a file, however they're arranged in the file, and replacing any non-number with 0 (instead of evaluating it)

   'a 1 2 b 3' fwrite 'arow'
9
   nums 'arow'
0 1 2 0 3

因此,让我们从您已将文件读入 J 环境这一点开始。

txt=: 1!:1 < F

txt 中,如果一个数字与另一个数字在不同的行上,则必须有一个 CR(回车 return)或 LF(换行)字符在字符之间(或者 CRLF 并列,具体取决于换行符的表示方式)。因此,如果我们使用 }(修正副词)

LFCR 字符替换为 ' '(空白 space)
txt1=: ' '  I.@: ( (CR , LF)  e.~ ]) } txt

则多行字符串变为一行。使用 0 ". 将该行转换为数字,您可以根据需要操作数字。

如果您知道每一行以空白开始或结束 space 那么您可以使用 -.

简单地删除 LFCR
txt1=: txt -. LF , CR

但是如果没有空格分隔的话,这会 运行 数字跨行在一起。

首先要处理的问题是行尾。使用标准库中的 freads 将读取您的文本文件并确保每一行都以 LF 终止,无论这些行最初是 CRLF、CR 还是只是 LF 终止。如果您想完全按照文件中的原样读取字节,请使用 fread,不带左参数。

让我们以下面的 space 分隔文件 (numbers.txt) 为例:

1 -3.93 17 -7 564
2 4.27 12 3 234
3 -1.90 22 5 728
4 0.00 10 -4 442

您可以阅读文件如下:

   0 ". 'm' freads 'numbers.txt'
1 _3.93 17 _7 564
2  4.27 12  3 234
3  _1.9 22  5 728
4     0 10 _4 442

在幕后 'm' freads 的左参数是这样做的:

   0 ". ];._2 freads 'numbers.txt'

;._2 表示使用文件中的最后一个字节(现在是 LF)作为分隔符,将它们从结果中删除并将动词应用于其左侧(] 在这种情况下)到每一行。结果是一个字符数组,每行一行,列对应文件中最长的行(较短的行用 spaces 填充)。 0 ". 然后尝试将数组解析为数字,如果不能,它将用 0 替换输入(我经常使用 _999 所以更明显的是有些东西没有正确转换)。

如果文件由 space 以外的其他内容分隔,则您需要解析这些字段,否则您会得到有趣的结果:

   0 ". ];._2 freads 'numbers.csv'
0 24.2712 0 0

如果它是一个简单的文件,您可以尝试以下之一:

   0 ". ];._2 ', ' charsub freads 'numbers.csv'  NB. replace delimiter with spaces
1 _3.93 17 _7 564
2  4.27 12  3 234
3  _1.9 22  5 728
4     0 10 _4 442

   0 ". > ','&cut;._2 freads 'numbers.csv'  NB. box fields in each line
1 _3.93 17 _7 564
2  4.27 12  3 234
3  _1.9 22  5 728
4     0 10 _4 442

如果它更复杂(带引号的定界符等)或者您只是觉得它更简单,您可以使用 tables/csv or tables/dsv 插件:

   load 'tables/csv'
   0 ". > readcsv 'numbers.csv'
1 _3.93 17 _7 564
2  4.27 12  3 234
3  _1.9 22  5 728
4     0 10 _4 442

   0 ". > ',' readdsv 'numbers.csv'
1 _3.93 17 _7 564
2  4.27 12  3 234
3  _1.9 22  5 728
4     0 10 _4 442