Seite 1 von 1
Ich will nur Latitude und Longitude
Verfasst: Freitag 26. April 2019, 10:40
von Strawk
Hallo!
Aus einer Datei mit allen Flughäfen der Welt im .csv-Format möchte ich nur die Längen- und Breitengrade der Flughäfen. Ich bekomme aber sämtliche Daten zurückgeliefert. Warum? Code:
Code: Alles auswählen
import pandas as pd
def get_airport_positions_from_file():
Cov = pd.read_csv("data\\airports.dat",
names = [# 'Airport',
# 'Name',
# 'City',
# 'Country',
# 'IATA',
# 'ICAO',
'Latitude',
'Longitude'
# 'Altitude',
# 'Timezone',
# 'DST',
# 'Tz',
# 'Type',
# 'Source'
], encoding='utf-8')
lon, lat = Cov['Longitude'], Cov['Latitude']
return lon, lat
if __name__ == "__main__":
lon, lat = get_airport_positions_from_file()
print(lon, lat)
Grüße, Strawk
Re: Ich will nur Latitude und Longitude
Verfasst: Freitag 26. April 2019, 10:51
von __blackjack__
@Strawk: Warum nicht? Woher soll die Funktion denn wissen das Du nicht alle willst, und vor allem auch welche Du denn willst? `names` gibt die Namen für die Spalten an die Du denen geben willst, nicht Namen die in der Datei stehen und an einer Liste mit zwei Einträgen kann der Rechner aber unmöglich erahnen welche zwei Spalten Du denn haben möchtest.
Zur Auswahl von Spalten gibt es aber auch ein Argument bei der Funktion.
Re: Ich will nur Latitude und Longitude
Verfasst: Freitag 26. April 2019, 11:01
von Strawk
Hallo!
Die Funktion hat eine Masse an Parametern. Einige habe ich ausprobiert. Erfolglos. Als Anfänger kann ich die zu verwendende nicht identifizieren. Hätte seine Programmier-Exzellenz die unendliche Güte, mir den Parameter zu nennen, den ich brauche, um fortzufahren? Danke.
Grüße
Strawk
12.05 Uhr
"usecols"?
Re: Ich will nur Latitude und Longitude
Verfasst: Freitag 26. April 2019, 12:08
von ThomasL
Wie wäre es einfach mal die pandas.read_csv API zu befragen?
https://pandas.pydata.org/pandas-docs/s ... d_csv.html
Mit nur einem kleinen Englischverständnis ist es dann wie von dir vermutet doch einfach
usecols : list-like or callable, optional
Return a subset of the columns. If list-like, all elements must either be positional (i.e. integer indices into the document columns) or strings that correspond to column names provided either by the user in names or inferred from the document header row(s). For example, a valid list-like usecols parameter would be [0, 1, 2] or ['foo', 'bar', 'baz']. Element order is ignored, so usecols=[0, 1] is the same as [1, 0].
zu lokalisieren.
Re: Ich will nur Latitude und Longitude
Verfasst: Freitag 26. April 2019, 17:15
von Strawk
Hallo!
Folgender Code liefert schon einiges:
Code: Alles auswählen
import pandas as pd
def get_airport_positions_from_file():
Cov = pd.read_csv("data\\airports.dat",
names = [# 'Airport',
# 'Name',
# 'City',
# 'Country',
# 'IATA',
# 'ICAO',
'Latitude',
'Longitude'
# 'Altitude',
# 'Timezone',
# 'DST',
# 'Tz',
# 'Type',
# 'Source'
], encoding='utf-8',
usecols=[6,7])
lat, lon = Cov['Latitude'], Cov['Longitude']
return lat.values, lon.values
if __name__ == "__main__":
lat, lon = get_airport_positions_from_file()
x = list(zip(lat,lon))
df = pd.DataFrame(x)
print(df)
In SQL würde mein Wunsch so formuliert:
Code: Alles auswählen
SELECT latitude, longitude FROM flughaefen WHERE country=‘island‘;
Wie aber in Python (Dataframe)?
Ausprobiert habe ich schon:
Code: Alles auswählen
# y = df.loc[df['column']==4]
# y = df(columns=[4])
# df = pd.DataFrame(index='Airport', columns=['Iceland'])
# print(df)
und vieles Ähnliche! Klappt noch nicht ganz.
Grüße
Re: Ich will nur Latitude und Longitude
Verfasst: Freitag 26. April 2019, 19:25
von snafu
@Strawk: Die Lösung ist immer noch der usecols-Parameter. Was passiert denn, wenn du den verwendest? Kommen andere Spalten heraus als du erwartest? Dann solltest du deine Indexwerte überprüfen, weil die sich dann offensichtlich nicht mit den tatsächlichen Indizes in deinen Daten decken. Du wirst dich womöglich auch bei der Benennung der Spalten irgendwo verzählt oder eine Spalte vergessen haben. Setze auf jeden Fall mal dort an anstatt wild Parameter einer dokumentierten API zu probieren...
EDIT: Oder erhälst du inzwischen lat und lon und willst nun an die Angaben für bestimmte Länder kommen? Das geht aus deinem letzten Beitrag leider nicht wirklich hervor. Hilfe bekommen heißt auch immer, die richtigen Fragen zu stellen und hier im Thread die möglicherweise erfolgreichen Schritte zur Lösung zu benennen, damit man weiß, wo du gerade stehst.
Re: Ich will nur Latitude und Longitude
Verfasst: Freitag 26. April 2019, 21:49
von Strawk
Hallo!
Denkfehler!
Nicht Spalten wollte ich selektieren, sondern Zeilen. Es ging darum, aus den 7184 weltweiten Flughäfen zu Kürzungszwecken nur die Islands herauszufiltern. Und da steht das Kriterium natürlich wiederholt in verschiedenen Zeilen, bei Spalte "country".
Das Ganze funktioniert jetzt und sieht so aus:
Code: Alles auswählen
10 Iceland 65.660004 -18.072701
11 Iceland 65.283302 -14.401400
12 Iceland 64.295601 -15.227200
13 Iceland 65.952301 -17.426001
14 Iceland 66.058098 -23.135300
15 Iceland 63.985001 -22.605600
16 Iceland 65.555801 -23.965000
17 Iceland 64.129997 -21.940599
18 Iceland 66.133301 -18.916700
19 Iceland 63.424301 -20.278900
4033 Iceland 63.556099 -20.137501
4137 Iceland 66.545800 -18.017300
4138 Iceland 66.218498 -15.335600
4139 Iceland 65.720596 -14.850600
5185 Iceland 65.655800 -16.918100
5555 Iceland 65.641296 -23.546200
5556 Iceland 65.995300 -21.326900
5557 Iceland 65.731697 -19.572800
5558 Iceland 63.929199 -21.037800
6482 Iceland 65.131897 -13.746400
Der dazugehörige Code:
Code: Alles auswählen
if __name__ == "__main__":
country, lat, lon = get_airport_positions_from_file()
x = list(zip(country, lat,lon))
df = pd.DataFrame(x)
y = df.loc[df[0] == 'Iceland']
print(y)
Code: Alles auswählen
import pandas as pd
def get_airport_positions_from_file():
Cov = pd.read_csv("data\\airports.dat",
names = [# 'Airport',
# 'Name',
# 'City',
'Country',
# 'IATA',
# 'ICAO',
'Latitude',
'Longitude'
# 'Altitude',
# 'Timezone',
# 'DST',
# 'Tz',
# 'Type',
# 'Source'
], encoding='utf-8',
usecols=[3,6,7])
country, lat, lon = Cov['Country'], Cov['Latitude'], Cov['Longitude']
return country.values, lat.values, lon.values
Danke für eure wertvollen Tipps!
Grüße
Strawk
Re: Ich will nur Latitude und Longitude
Verfasst: Freitag 26. April 2019, 22:13
von snafu
Das ist aber reichlich umständlich geworden. Du machst doch schon bei
read_csv() alle nötigen Vorbereitungen. Wenn du jetzt nur Island haben willst:
Code: Alles auswählen
df = pd.read_csv(...)
print(df[df.Country == 'Iceland'])
Wenn man einmal einen
DataFrame hat, dann benutzt man normalerweise auch diesen sinnvoll weiter. Ein Transformieren in Python-Listen,
zip(), usw entfällt alles, wenn man
pandas richtig benutzt. Ansonsten hat man viel mehr Code als nötig und beschäftigt den Rechner mit unnötiger zusätzlicher Arbeit.
Re: Ich will nur Latitude und Longitude
Verfasst: Samstag 27. April 2019, 09:52
von Strawk
Hallo ihrs!
Programm jetzt:
Code: Alles auswählen
# -*- coding: utf-8 -*-
"""
Created on Fri Apr 26 10:45:34 2019
@author: Karl Kraft
"""
import pandas as pd
def get_airport_positions(country, airport_file):
csvData = pd.read_csv(airport_file,
names = [# 'Airport',
# 'Name',
# 'City',
'Country',
# 'IATA',
# 'ICAO',
'Latitude',
'Longitude'
# 'Altitude',
# 'Timezone',
# 'DST',
# 'Tz',
# 'Type',
# 'Source'
], encoding='utf-8',
usecols=[3,6,7])
countrydata, lat, lon = csvData['Country'], csvData['Latitude'], csvData['Longitude']
df = pd.DataFrame(list(zip(countrydata, lat,lon)))
coords = df.loc[df[0] == country]
numberAirports = coords[0].count()
coords.index = range(numberAirports)
return coords
'''
def calculate_distances(self):
"""
calculates all the single distances between each two adjoining points
"""
df = self.df
if self.dim == 2:
geopoints = list(zip(df['lat'], df['lon']))
else: # dim == 3
geopoints = list(zip(df['lat'], df['lon'], df['alt']))
Npoints = len(geopoints)
lstDistances = []
for i in range(0, Npoints-1):
lstDistances.append(dist(geopoints[i], geopoints[i+1], self.method, self.dim))
return lstDistances
def dist(coord1, coord2, method="karney", dim=2):
"""
calculates distance between two coordinates (= tuples of (lat,lon)).
Available methods: "karney", "vincenty" and "great_circle"
"""
if dim not in [2,3]:
raise ValueError("Invalid dimension: %s" % (dim))
if method == "karney":
d = distance.distance(coord1, coord2).m
elif method == "vincenty":
d = distance.vincenty(coord1, coord2).m
elif method == "great_circle":
d = distance.great_circle(coord1, coord2).m
else:
raise ValueError("unknown method for distance calculation: %s" % method)
if dim == 3:
if not (len(coord1) == 3 and len(coord2) == 3):
raise TypeError("elevation not available: coord1 = %s, coord2 = %s" % (coord1, coord2))
d3 = coord2[2] - coord1[2]
d = np.sqrt(d*d+d3*d3)
return d
'''
if __name__ == "__main__":
coords = get_airport_positions(country="Iceland", airport_file="data\\airports.dat")
print(coords)
Zur Erinnerung: Das Fernziel ist es, den Abstand in Kilometern aller Flughäfen der Welt zueinander zu berechnen. Um die Rechenoperationen zunächst gering zu halten, wurden im Vor-Thread nur die isländischen Flughäfen ausgewählt. 20 an der Zahl. Gehen wird nun einmal davon aus, es handle sich zunächst um 10 Flughäfen. Bzw. hier deren Positionen in Breiten- und Längengrad angegeben. Zur Berechnung ergibt sich eine Matrix wir folgt: 10 Flughafenpositionen in den Zeilen, 10 in der Spalten. Jetzt hat die Matrix noch 100 Elemente. Es liegt ja nun in der Natur der Sache, dass die Positionen zu sich selbst nicht berechnet werden können/müssen. Es wäre sinnfrei, den Abstand des Flughafens A zum Flughafen A zu berechnen. Es ergibt sich also eine 10-elementige Diagonale, womit die Elemente auf 90 schrumpfen. Siehe Bild unten. Ebenso sinnfrei wäre es, nachdem ich den Abstand des Flughafens A zu B ermittelt habe, auch den B zu A zu ermitteln, denn der ist logischerweise identisch. Folglich genügt es, die Elemente oberhalb (oder unterhalb) der Diagonale zu ermitteln. Damit sind wir bei 45 notwendigen Berechnungen. Frage nun: aus dem Python-Dataframe eine solche Matrix erstellen, und dann über Vektoren die Berechnungen durchführen. Denn sonst würde die Berechnung später aller 7100 Flughäfen Stunden dauert. Also: Matrix aus Dataframe, Vektorberechnung, wie macht man das in Python?
Grüße Strawk
Bild:
https://ibb.co/v1nD3nv
Re: Ich will nur Latitude und Longitude
Verfasst: Samstag 27. April 2019, 10:56
von __blackjack__
@Strawk: Was genau ist der Grund die (einzigen) drei Spalten aus dem eingelesenen `DateFrame` zu nehmen, mit `zip()` zu einer Liste aus Tupeln zu machen, um daraus dann wieder einen `DataFrame` zu erstellen?
Ausserdem solltest Du Dir mal die `reset_index()`-Methode anschauen.
Re: Ich will nur Latitude und Longitude
Verfasst: Samstag 27. April 2019, 11:04
von __blackjack__
Kann es sein, dass Du
scipy.spatial.distance.pdist suchst?
Re: Ich will nur Latitude und Longitude
Verfasst: Sonntag 28. April 2019, 11:43
von Strawk
Hallo _blackjack_!
Ich bekomme
AttributeError: module 'scipy' has no attribute 'spatial'
Grüße
Strawk
Re: Ich will nur Latitude und Longitude
Verfasst: Sonntag 28. April 2019, 11:46
von __blackjack__
@Strawk: Ich nicht.
Re: Ich will nur Latitude und Longitude
Verfasst: Sonntag 28. April 2019, 11:55
von Strawk
@_blackjack_: Lösung hierfür
import scipy.spatial
anstatt
import scipy
Entschuldigung für den spontanen Thread-Eintrag, ohne zuvor zu googeln.