0

Given the following script to read in latitude, longitude, and magnitude data:

#!/usr/bin/env python

# Read in latitudes and longitudes
eq_data = open('lat_long')

lats, lons = [], []

for index, line in enumerate(eq_data.readlines()):
    if index > 0:
        lats.append(float(line.split(',')[0]))
        lons.append(float(line.split(',')[1]))

#Build the basemap
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import numpy as np

antmap = Basemap(projection='spstere', boundinglat=-20, lon_0=-60, resolution='f')
antmap.drawcoastlines(color='0.50', linewidth=0.25)
antmap.fillcontinents(color='0.95')

x,y = antmap(lons, lats)
antmap.plot(x,y, 'r^', markersize=4)
plt.show()

I receive the following error when attempting to read in the latitudes, longitudes, and magnitudes:

Traceback (most recent call last):
  File "./basic_eqplot.py", line 10, in <module>
    lats.append(float(line.split(',')[0]))
ValueError: invalid literal for float(): -18.381  -172.320  5.9

The input file looks something like:

-14.990,167.460,5.6
-18.381,-172.320,5.9
-33.939,-71.868,5.9
-22.742,-63.571,5.9
-2.952,129.219,5.7

Any ideas for why this would cause a hiccup?

geeb.24
  • 527
  • 2
  • 7
  • 25
  • maybe this will help you http://stackoverflow.com/questions/21943877/python-valueerror-invalid-literal-for-float – Lawrence Benson Sep 01 '15 at 14:42
  • 5
    One of the lines in the input file is using `space` to delimit the latitudes and longitudes , instead of comma, did you check that? – Anand S Kumar Sep 01 '15 at 14:45
  • The string `"-18.381 -172.320 5.9".split(',')` (see the traceback you posted) is going to yield `["-18.381 -172.320 5.9"]`. – chucksmash Sep 01 '15 at 14:48
  • So, how my code is written above, I'd ideally like to split each row on the comma, and then assign the first column to `lats` and the second column to `lons`. I'm confused as to why the above code won't work. Thanks your for the help. – geeb.24 Sep 01 '15 at 14:55

2 Answers2

5

It appears you have one or more lines of corrupt data in your input file. Your traceback says as much:

ValueError: invalid literal for float(): -18.381  -172.320  5.9

Specifically what is happening:

  1. The line -18.381 -172.320 5.9 is read in from eq_data.
  2. split(',') is called on the string "-18.381 -172.320 5.9". Since there is no comma in the string, the split method returns a list with a single element, the original string.
  3. You attempt to parse the first element of the returned array as a float. The string "-18.381 -172.320 5.9" cannot be parsed as a float and a ValueError is raised.

To fix this issue, double check the format of your input data. You might also try surrounding this code snippet in a try/except block to give you a bit more useful information as to the specific source of the problem:

for index, line in enumerate(eq_data.readlines()):
    if index > 0:
        try:
            lats.append(float(line.split(',')[0]))
            lons.append(float(line.split(',')[1]))
        except ValueError:
            raise ValueError("Unable to parse input file line #%d: '%s'" % (index + 1, line))
chucksmash
  • 5,777
  • 1
  • 32
  • 41
  • Oh and in general, @fpierfed is correct. I've specifically tried to help you understand why you are seeing the error you are seeing so I've stayed pretty true to your original code but you really should use the csv module to parse csv files. – chucksmash Sep 01 '15 at 15:08
  • Thank you for the great description, chucksmash. It turned out that stupidly, I was reading in a file that was not delimited by commas, but rather spaces, causing the error when trying to split on the comma rather than the whitespace. Thank you for the clarification. +1. – geeb.24 Sep 01 '15 at 15:10
  • Thanks for the tip about the csv module. I'll definitely use that in the future. – geeb.24 Sep 01 '15 at 15:11
5

What is probably going on is that your input file has a malformed line where a space is used to separate fields instead of a comma.

As a consequence, the result of line.split(',')[0] is the whole input line (in your case "-18.381 -172.320 5.9").

More in general: for these types of problems I really like to use the Python cvs module to parse the input file:

import csv
with open('lat_long', 'r') as csvfile:
    reader = csv.reader(csvfile)
    for row in reader:
        assert len(row) == 3
        lst, lon, mag = row
        ...

An alternative would be to use tools like pandas; but that might be overkill in some cases.

fpierfed
  • 71
  • 5