Я пытаюсь сделать некоторые основы математики с файлами в J - PullRequest
2 голосов
/ 14 марта 2020

У меня есть файл с числами, разделенными пробелом (не CSV-файл, а обычный текстовый файл) Следующий код будет суммировать числа, появляющиеся в непрерывной строке.

+/ 0". 1!:1 < F

(0". для преобразование строк в числа) (F - текстовый файл)

Но если каждое число появляется в отдельной строке, это не работает. Как мне изменить код, чтобы сделать это? И некоторые общие указатели для анализа J-speci c цифр c с файлами.

Ответы [ 3 ]

3 голосов
/ 21 марта 2020

Первая проблема, с которой нужно разобраться - это окончания строк. Использование freads из стандартной библиотеки прочитает ваш текстовый файл и обеспечит завершение каждой строки LF, независимо от того, были ли строки изначально CRLF, CR или просто LF. Используйте fread без левого аргумента, если вы хотите прочитать байты в точности так, как они были в файле.

Давайте в качестве примера воспользуемся следующим файлом, разделенным пробелом (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), удалите их из результата и примените глагол слева (в данном случае ]) к каждой строке. Результатом является массив символов со строкой для каждой строки и столбцами, соответствующими самой длинной строке в файле (более короткие строки дополняются пробелами). Затем 0 ". пытается проанализировать массив как числа, где он не может заменить входные данные на 0 (я часто использую _999, так что более очевидно, что что-то не преобразовалось правильно).

Если файл разделен чем-то отличным от пробела, то вам нужно проанализировать поля, иначе вы получите интересные результаты:

   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

Если это более сложно (цитируемые разделители и c) или если вам просто проще, вы можете использовать tables/csv или 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
3 голосов
/ 14 марта 2020

Рассмотрим:

$ 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, только с той разницей в форме. Если вам удобно указывать c глаголы приема файлов для указания c расположения чисел в файлах, вы можете остановиться здесь.

Но это также может быть полезно:

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

С , ( ravel ) это просто дает вам числа из файла, однако они располагаются в файле, и заменяет любое не-число на 0 ( вместо его оценки *). 1017 *)

   'a 1 2 b 3' fwrite 'arow'
9
   nums 'arow'
0 1 2 0 3
2 голосов
/ 14 марта 2020

Итак, давайте возьмем его с того момента, как вы прочитали свой файл в среду J.

txt=: 1!:1 < F

В txt, если число находится в строке, отличной от другой, то должно быть число Символ CR (возврат каретки) или LF (перевод строки) между символами (или, может быть, CRLF наложение в зависимости от способа представления перевода строки). Таким образом, если мы заменим эти LF и CR символы на ' ' (пробел), используя } (Изменить наречие)

txt1=: ' '  I.@: ( (CR , LF)  e.~ ]) } txt

, тогда многострочная строка станет одной строкой. Преобразуйте эту строку в числа, используя 0 "., и вы можете манипулировать своими числами, когда вы будете sh.

Если вы знали, что каждая строка либо начиналась, либо заканчивалась пробелом, вы могли бы просто удалить LF и CR, используя -.

txt1=: txt -. LF , CR

, но для этого использовались бы числа вместе, если не было пробелов для их разделения.

...