我正在尝试用 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
并列,具体取决于换行符的表示方式)。因此,如果我们使用 }
(修正副词)
将 LF
和 CR
字符替换为 ' '
(空白 space)
txt1=: ' ' I.@: ( (CR , LF) e.~ ]) } txt
则多行字符串变为一行。使用 0 ".
将该行转换为数字,您可以根据需要操作数字。
如果您知道每一行以空白开始或结束 space 那么您可以使用 -.
简单地删除 LF
和 CR
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
我有一个由 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
并列,具体取决于换行符的表示方式)。因此,如果我们使用 }
(修正副词)
LF
和 CR
字符替换为 ' '
(空白 space)
txt1=: ' ' I.@: ( (CR , LF) e.~ ]) } txt
则多行字符串变为一行。使用 0 ".
将该行转换为数字,您可以根据需要操作数字。
如果您知道每一行以空白开始或结束 space 那么您可以使用 -.
LF
和 CR
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