Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extract columns using "genfromtxt"

I've already read these 2 questions before asking this one (q1 and q2) but I haven't found any satisfying answer

I need to extract two columns from a 2D-array without using pandas or loadtxt, but with genfromtxt

For now, what I did is:

X = np.genfromtxt('File1.csv', 
                    delimiter='\t', 
                    skip_header=0, skip_footer=0, 
                    names=True , usecols=("Time") )

Y = np.genfromtxt('File1.csv', 
                    delimiter='\t', 
                    skip_header=0, skip_footer=0, 
                    names=True , usecols=("Profit") )

then, using matplotlib I plot Y vs X, result is perfect

Now, I was thinking that I should do it the "right" way and avoid reading twice the array. So I tried the unpack feature:

 X, Y = np.genfromtxt('File1.csv', 
                    delimiter='\t', 
                    skip_header=0, skip_footer=0, 
                    names=True , usecols=("Time", "Profit"), unpack=True )

I get the message: too many values to unpack

Now if I write the previous command with one vector for the output (say Z) without unpacking, the vector Z will contain a tuple that cannot be plotted directly.

Any solution to this simple-looking problem ?

like image 299
SAAD Avatar asked Aug 06 '26 04:08

SAAD


1 Answers

When you have more than one named field, you will have a 1-d structured array, like so:

>>> np.genfromtxt('File1.csv', delimiter='\t', names=True, usecols=("Time", "Profit"))
array([(0.0, 1.0), (2.0, 3.0), (3.0, 4.0), (5.0, 6.0)], 
      dtype=[('Time', '<f8'), ('Profit', '<f8')])

You can't unpack a 1d structured array, since all that unpack=True does is to transpose your array so that columns vary along the first axis, and the transpose of a 1d array is itself. Thus, you get the same result with unpack:

>>> np.genfromtxt('File1.csv', delimiter='\t', names=True, usecols=("Time", "Profit"), unpack=True)
array([(0.0, 1.0), (2.0, 3.0), (3.0, 4.0), (5.0, 6.0)], 
      dtype=[('Time', '<f8'), ('Profit', '<f8')])

Even if you use numbers in your usecols argument as @Roberto suggests, you still have the problem because using names=True gives you a structured array if you have more than one field (which is why you didn't notice it with your first attempt).

If you save this as Z, you can plot it like

plt.plot(Z['Time'], Z['Profit'])

or you can split it as you originally asked:

X, Y = Z['Time'], Z['Profit']
like image 140
askewchan Avatar answered Aug 08 '26 17:08

askewchan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!