Ich will nur Latitude und Longitude

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
Strawk
User
Beiträge: 244
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

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
Ich programmiere erfolglos, also bin ich nicht.
Benutzeravatar
__blackjack__
User
Beiträge: 14042
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Benutzeravatar
Strawk
User
Beiträge: 244
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

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"?
Ich programmiere erfolglos, also bin ich nicht.
Benutzeravatar
ThomasL
User
Beiträge: 1378
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

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.
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Benutzeravatar
Strawk
User
Beiträge: 244
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

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
Ich programmiere erfolglos, also bin ich nicht.
Benutzeravatar
snafu
User
Beiträge: 6866
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@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.
Benutzeravatar
Strawk
User
Beiträge: 244
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

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
Ich programmiere erfolglos, also bin ich nicht.
Benutzeravatar
snafu
User
Beiträge: 6866
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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.
Benutzeravatar
Strawk
User
Beiträge: 244
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

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
Ich programmiere erfolglos, also bin ich nicht.
Benutzeravatar
__blackjack__
User
Beiträge: 14042
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Benutzeravatar
__blackjack__
User
Beiträge: 14042
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Kann es sein, dass Du scipy.spatial.distance.pdist suchst?
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Benutzeravatar
Strawk
User
Beiträge: 244
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Hallo _blackjack_!

Ich bekomme
AttributeError: module 'scipy' has no attribute 'spatial'

Grüße
Strawk
Ich programmiere erfolglos, also bin ich nicht.
Benutzeravatar
__blackjack__
User
Beiträge: 14042
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Strawk: Ich nicht.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Benutzeravatar
Strawk
User
Beiträge: 244
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

@_blackjack_: Lösung hierfür
import scipy.spatial
anstatt
import scipy
Entschuldigung für den spontanen Thread-Eintrag, ohne zuvor zu googeln.
Ich programmiere erfolglos, also bin ich nicht.
Antworten