Search code examples
j

Importing csv file into J and using them as variable


I saved this data (20 vectors v)into csv file like this

v=:<"1 (? 20 2 $ 20)
makecsv v
v writecsv jpath'~temp/position.csv'
]vcsv =: freads jpath '~temp/position.csv'
fixcsv vcsv

, and I could import the csv file by

readcsv jpath '~temp/position.csv'

However, it doesn't give same result if I name it as

w=: readcsv jpath '~temp/position.csv'
diff=: ([{]) ,. ]

0 diff v
0 diff w

Actually, 0 diff w gives a length error

Is there any other approach should I use to have same results from both v(original) and w(imported csv data)?

Thank you!


Solution

  • When you write the CSV file, you just have a bunch of ASCII characters. In this case, you've got numbers, spaces, and commas.

    When you read the CSV, J has no guarantees about the format or contents. fixcsv gets your commas and line-breaks translated into a grid of cells, but J boxes it all to be safe, because it's a bunch of variable-length ASCII strings.

    If you want to get back to v, you have two things you need to do. The first is to get the dimensions right. CSV files, pretty much by definition, are two-dimensional. If you change your example to write a two-dimensional array to the CSV, you'll find that you have the same shape after fixcsv readcsv.

    u =: 4 5 $ v
       u writecsv jpath'~temp/position.csv'
    104
       ] t =: fixcsv freads jpath '~temp/position.csv'
    ┌────┬─────┬────┬────┬─────┐
    │9 11│1 4  │8 3 │3 12│5 4  │
    ├────┼─────┼────┼────┼─────┤
    │7 11│10 11│9 10│0 8 │6 16 │
    ├────┼─────┼────┼────┼─────┤
    │13 8│17 12│13 2│5 19│17 14│
    ├────┼─────┼────┼────┼─────┤
    │2 15│19 10│3 1 │12 7│14 13│
    └────┴─────┴────┴────┴─────┘
       $ v
    20
       $ u
    4 5
       $ t
    4 5
    

    If you're definitely dealing with a one-dimensional list (albeit of boxed number pairs), then you can Ravel (,) what you read to get it down to one dimension.

       $ w
    1 20
       $ , w
    20
    

    Once you have them in the same shape, you need to convert the ASCII text into number arrays. Do that with Numbers (".).

       10 * > {. v
    90 110
       10 * > {. , w
    |domain error
    |   10    *>{.,w
       'a' , > {. , w
    a9 11
       10 * _ ". > {. , w
    90 110