2

I have a pretty simple issue: I need to convert the file with geographical coordinates like

Lat         Long
50 0 50     35 1 40
50 2 50     35 10 20
50 3 1      35 13 22
50 2 38     35 14 40
49 59 6     35 13 22
49 57 14    35 13 21
49 57 10    35 13 0
49 57 0     35 6 20

to the

Lat      Long
50.01389,35.02778
50.04722,35.17222
etc.

Math is as simple as a pie: we have to devide minutes (0 and 1 in this particular case) by 60 and seconds (50 and 40) by 3600, then add these numbers and we will get the remainder of the degree (50 and 35).

Here is my script with numpy. I suppose, it looks to big for such a simple conversion, however I don't know how to do this simpler. Also I don't know how to end this script, so it could do what it should. Now it ends with adding minutes and seconds.

import sys
import numpy as np


filename = input('Please enter the file\'s name: ')
with open(filename, "r") as f:
    sys.stdout = open('%s (converted).txt' % f.name, 'a')

    data = np.loadtxt(f)
    degree_lat, degree_long = data[:, 0], data[:, 3]
    min_lat, sec_lat, min_long, sec_long = \
        (data[:, 1] / 60), (data[:, 2] / 3600), (data[:, 4] / 60), (data[:, 5] / 3600)

    remainder_lat, remainder_long = min_lat + sec_lat, min_long + sec_long

    degree_result_lat = degree_lat + remainder_lat
    degree_result_long = degree_long + remainder_long

Any suggestions would be greatly appreciated! Thanks and sorry for the amateur questions.

7
  • Can you post a few example lines of your input file? Also what are you trying to achieve with sys.stdout = open...? Commented Jun 1, 2016 at 7:33
  • Is this a question about how to optimize/minimize your code? You might want to check out codereview then. Commented Jun 1, 2016 at 7:50
  • @NilsWerner I have just updated this topic. You can find an example of the input file in the top of it. Commented Jun 1, 2016 at 8:00
  • @OliverW. Thanks for the link, I will) Commented Jun 1, 2016 at 8:00
  • That script and the data you provided do not run, it fails with ValueError: could not convert string to float: Lat. Commented Jun 1, 2016 at 8:02

2 Answers 2

2

If I understand correctly what you have in data array,

data = data.T # not strictly necessary, but simplifies following indexing

lat = data[0]+data[1]/60.+data[2]/3600.
lon = data[3]+data[4]/60.+data[5]/3600.

converted = np.vstack((lat,lon)).T

np.savetxt(outname, converted)

Line by line comment

  1. data.T transposes the array, columns becomes tows and in Python it's easier to address rows than columns...
  2. data[0]+data[1]/60.+data[2]/3600. is a vectorized expression, each row of the data array is an array on its own, and you can evaluate algebraic expressions, possibly using also numpy's functions that accept, as arguments, vector expressions as well.
  3. as above…
  4. np.vstack((lat,lon)).T we have two names that reference two different expressions, we want to combine them in a single array, so that we can use np.savetxt() to save it. Using np.vstack() we get an array like

    [[lt0, lt1, ..., ltN],
     [ln0, ln1, ..., lnN]]
    

    but we want to save an array like

    [[lt0, ln0],
     [lt1, ln1],
     ...
    

    so we have to transpose the result of np.vstack()

  5. np.savetxt(outname, converted) we save at once the whole array using one of the convenient conveniency functions offered by the numpy libraries.

Note that, when using numpy you should try to avoid explicit loops and instead relying on its ability to vectorize most expressions. This leads to much more efficient code.

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you, this works as well) I didn't know about ".T", it seems to a pretty usefull option.
It works better, because 1. you avoid the overload connected to the execution of explicit loops in an interpreted language and 2. the output file is properly formatted, and can be loaded by np.loadtxt().
Wow, many thanks for the very detailed answer, for the vectorizing and others. I will try to do my work in more Pythonic way and get rid of the loops. For now, this looks even more simpler)
I think that this is redundant, but I'd like anyway to stress that it's only numpy and the use of its arrays that allows you to avoid explicit loops... it doesn't work with ordinary Python's lists.
2

This can be done in a more Pythonic way as follows.

import numpy as np
f = open('data.txt','r')
data = np.loadtxt(f)
coords = [(el[:3],el[3:]) for el in data]
print coords
output = [(c[0][0]+c[0][1]/60.+c[0][2]/3600.,c[1][0]+c[1][1]/60.+c[1][2]/3600.) for c in coords]
print output    

Output :

[(50.013888888888886, 35.027777777777779),
 (50.047222222222217, 35.172222222222217),
 (50.050277777777772, 35.222777777777779),
 (50.043888888888887, 35.244444444444447),
 (49.984999999999999, 35.222777777777779),
 (49.953888888888891, 35.222500000000004),
 (49.952777777777783, 35.216666666666669),
 (49.950000000000003, 35.105555555555554)]  

Explanation

Line 4: Loads the co-ordinates in coords as tuples
Line 5: For each co-ordinate in coords calculates the co-ordinate in decimal system and assigns them to output as tuples

2 Comments

Abdul, great, thanks for the more Pythonic result and explanation)
By the way, how can I get rid of the tuple in the output file? I tries to use the for-loop and .join but it didn't help. Is there any simple option?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.