kcw78
kcw78

Reputation: 7996

np.genfromtxt returns a list, not an array

I'm using np.genfromtxt() to read a series of comma delimited text files and load into NumPy arrays for downstream processing (and eventually writing to HDF5).
The code works fine (returns an array) when there are 4 (or more) lines (1 header, 2+ data lines, 1 footer). A check of the array.shape after reading 4 lines gives (2, ). (first and last lines are not read)

I don't understand what is returned when I only have 3 lines (1 header, 1 data line, 1 footer). A check of the array.shape gives () and when I print the array, are no brackets []. I think it's a list. What do I need to do to get an array when np.genfromtxt() only finds one line of data?

I created an example to mimic the behavior with 2 simple files. (Data and Output follow the source code). Notes: The field names and data type are defined with np.dtype. I use skip_header=1, skip_footer=1 to skip the first and last lines, and usecols=() to only read some columns.

import numpy as np
import glob
dsp_dt = np.dtype ( [('H','S2'), ('YYMMDD',int),  
          ('NAME','S40'), ('COUNT',int)] )

for dsp_name in glob.glob('data_2019-10-*.txt'):
    print(dsp_name)

    dsp_recarr = np.genfromtxt(dsp_name, delimiter=',', dtype=dsp_dt, 
                               skip_header=1, skip_footer=1, usecols=(1,2,3),
                               names=None, encoding=None)
    print(dsp_recarr.dtype)
    print(dsp_recarr.shape)
    print(dsp_recarr)

File:data_2019-10-01.txt

H,YYMMDD,NAME,COUNT
S,191001,NAME_1,13
S,191001,Overall,13
F,191001

File:data_2019-10-02.txt

H,YYMMDD,NAME,COUNT
D,191002,NODATA,0
F,191002

Output:

data_2019-10-01.txt
[('YYMMDD', '<i4'), ('NAME', 'S40'), ('COUNT', '<i4')]
(2,)
[(191001, b'NAME_1', 13) (191001, b'Overall', 13)]

data_2019-10-02.txt
[('YYMMDD', '<i4'), ('NAME', 'S40'), ('COUNT', '<i4')]
()
(191002, b'NODATA', 0)

Upvotes: 0

Views: 1149

Answers (1)

hpaulj
hpaulj

Reputation: 231325

In [92]: dsp_dt = np.dtype ( [('H','S2'), ('YYMMDD',int),   
    ...:           ('NAME','S40'), ('COUNT',int)] )                                              
In [93]: txt="""H,YYMMDD,NAME,COUNT 
    ...: S,191001,NAME_1,13 
    ...: S,191001,Overall,13 
    ...: F,191001"""                                                                             
In [94]:                                                                                         
In [94]: dsp_recarr = np.genfromtxt(txt.splitlines(), delimiter=',', dtype=dsp_dt,  
    ...:                                skip_header=1, skip_footer=1, usecols=(1,2,3), 
    ...:                                names=None, encoding=None)                               
In [95]: dsp_recarr                                                                              
Out[95]: 
array([(191001, b'NAME_1', 13), (191001, b'Overall', 13)],
      dtype=[('YYMMDD', '<i8'), ('NAME', 'S40'), ('COUNT', '<i8')])
In [96]: _.shape                                                                                 
Out[96]: (2,)

With only one data line:

In [97]: dsp_recarr = np.genfromtxt(txt.splitlines(), delimiter=',', dtype=dsp_dt,  
    ...:                                skip_header=1, skip_footer=2, usecols=(1,2,3), 
    ...:                                names=None, encoding=None)                               
In [98]: dsp_recarr                                                                              
Out[98]: 
array((191001, b'NAME_1', 13),
      dtype=[('YYMMDD', '<i8'), ('NAME', 'S40'), ('COUNT', '<i8')])
In [99]: _.shape                                                                                 
Out[99]: ()
In [100]: print(dsp_recarr)                                                                      
(191001, b'NAME_1', 13)

loadtxt has a ndim, I don't see the equivalent in genfromtxt.

With reshaping:

In [107]: dsp_recarr.reshape(1)                                                                  
Out[107]: 
array([(191001, b'NAME_1', 13)],
      dtype=[('YYMMDD', '<i8'), ('NAME', 'S40'), ('COUNT', '<i8')])
In [108]: print(dsp_recarr.reshape(1))                                                           
[(191001, b'NAME_1', 13)]

Upvotes: 1

Related Questions