2017-04-16 4 views
1

ich mit dem folgenden Datenrahmen zu tun habe:Wie pandas Datenrahmen zu filtern?

 id1  id2  lat  lon 
    0 1  2  18.46290 -66.10301 
    1 1  2  37.549  -71.477 
    2 1  2  41.490  -71.326 
    3 0  0  0.0  0.0 
    4 1  3  42.058  -70.577 
    5 1  3  42.402  -70.642 
    6 1  3  41.589  -71.281 
    7 1  3  37.649  -71.440 
    8 0  0  0.0  0.0 
    9 2  2  18.462  -66.103 
    10 2  2  18.44857 -66.089 
    11 2  2  42.242  -70.97 
    12 0  0  0.0  0.0 

Die obigen Daten Bahndaten sind, und ich möchte alle Bahnen finden, die beginnen oder in einer Stadt endet, sagen NYC.

Jede Trajektorie hat mehrere Punkte, und die Trajektorien sind durch alle 0-Zeilen im obigen df getrennt.

Also, Zeilen 0-2 ist eine Trajektorie, Zeilen 4-7 andere und so weiter. (Auch wenn alle 0-Zeilen entfernt werden müssen, identifizieren "id1" und "id2" zusammen die verschiedenen Trajektorien, wie wir sehen können, wenn id1 oder id2 sich ändern, erhalten wir eine neue Trajektorie).

Ich habe eine andere df, sagen df2 die alle Koordinaten eines bestimmten Region der Stadt enthält, in dem ich die Bahnen beschränkt werden soll:

  lat  lon 
     0 40.711 -70.000 
     1 40.734 -70.099 
     2 40.740 -70.110 
     3 40.750 -70.120 

ich den ersten Punkt übereinstimmen soll und die zuletzt Punkt jeder Trajektorie von df1 mit den Koordinaten in df2, wenn entweder der erste Punkt ODER der letzte Punkt mit einem Koordinatenpaar in df2 übereinstimmt, möchte ich nur diese Trajektorien behalten.

(Wie ich erwähnt habe, möchte ich nur Trajektorien behalten, die in der Stadt enden und beginnen, also im Fall von "Zeilen 0-2" in df1, würde ich lat und lon von Zeile 0 (Startpunkt) und Zeile 2 (Endpunkt einer Trajektorie) mit df2, für "Zeilen 4-7" würde ich lat und lon von Zeile 4 (Startpunkt) und dann Zeile 7 (Endpunkt) usw. für das ganze df anpassen).

Vielleicht könnte ich die Lösung gefunden haben, wenn ich nur für die Zeilen mit bestimmtem „lat“ und „lon“, wie im folgenden Code habe suchen:

 mask = ((df["lat"].isin(df2["lat"])) && (df["lon"].isin(df2["lon"]))) 
     new_df = pd.DataFrame(df[mask]) 
     new_df.head() 

Aber ich habe abzufragen, um die Start- und Endpunkt jeder Bahn, die durch Nullen getrennt sind. Ich habe keine Ahnung, wie das geht.

Ich hoffe, die Frage ist klar, lassen Sie mich wissen, wenn etwas unklar ist.

Jede Hilfe wäre willkommen.

+0

Hat der 'df2' DF wirklich enthält __all__ Koordinaten einer bestimmten Region der Stadt - ist das überhaupt möglich? Wie genau sind diese Koordinaten? – MaxU

+0

@MaxU Nein, df2 dient nur zur Illustration. – Liza

+0

Ich fragte nach Ihren realen Daten ... Betrachten Sie dieses Beispiel: Sie haben den ersten Punkt einer Flugbahn mit Koordinaten: '(40.7111, -70.0001)' und in 'df2' haben Sie' (40.711, -70.000) ' - sie stimmen nicht überein – MaxU

Antwort

2

Betrachten Sie die folgende Eingabedatenrahmen:

In [158]: df 
Out[158]: 
    id1 id2  lat  lon 
0  1 2 18.46290 -66.10301 
1  1 2 37.54900 -71.47700 
2  1 2 41.49000 -71.32600 
3  0 0 0.00000 0.00000 
4  1 3 42.05800 -70.57700 # matching point 
5  1 3 42.40200 -70.64200 
6  1 3 41.58900 -71.28100 
7  1 3 37.64900 -71.44000 
8  0 0 0.00000 0.00000 
9  2 2 18.46200 -66.10300 
10 2 2 18.44857 -66.08900 
11 2 2 42.24200 -70.97000 # matching point 
12 0 0 0.00000 0.00000 

In [159]: df2 
Out[159]: 
     lat  lon 
0 40.711 -70.000 
1 40.734 -70.099 
2 40.740 -70.110 
3 40.750 -70.120 
4 42.058 -70.577 # matching point 
5 42.242 -70.970 # matching point 

wir Indizes der Start- und Endpunkte für alle Bahnen finden:

In [164]: idx = df.loc[(df.id1!=0) & (df.id2!=0)] \ 
    ...:   .groupby(['id1','id2'])['lat','lon'] \ 
    ...:   .apply(lambda x: pd.Series([x.index[0], x.index[-1]])) \ 
    ...:   .stack() \ 
    ...:   .values 
    ...: 

In [165]: idx 
Out[165]: array([ 0, 2, 4, 7, 9, 11], dtype=int64) 

Lassen Sie uns Koordinaten zu 100 multiplizieren und sie auf ganze Zahlen gestutzt (weil Vergleich schwebt in Python/Pandas ist "böse"):

df2 = df2.mul(100).astype(int) 

# `d` - will contain only starting and ending points for each trajectory 
d = df.loc[idx] 
d.loc[:, ['lat','lon']] = d[['lat','lon']].mul(100).astype(int) 

jetzt wir haben alle Koordinaten als ganze Zahlen:

In [185]: d.merge(df2) 
Out[185]: 
    id1 id2 lat lon 
0 1 3 4205 -7057 
1 2 2 4224 -7097 

und es wieder mit dem ursprünglichen DF fusionieren:

In [181]: d 
Out[181]: 
    id1 id2 lat lon 
0  1 2 1846 -6610 
2  1 2 4149 -7132 
4  1 3 4205 -7057 
7  1 3 3764 -7144 
9  2 2 1846 -6610 
11 2 2 4224 -7097 


In [163]: df2 
Out[163]: 
    lat lon 
0 4071 -7000 
1 4073 -7009 
2 4074 -7011 
3 4075 -7012 
4 4205 -7057 
5 4224 -7097 

so können wir sie leicht verschmelzen

In [186]: d.merge(df2)[['id1','id2']].merge(df) 
Out[186]: 
    id1 id2  lat  lon 
0 1 3 42.05800 -70.577 
1 1 3 42.40200 -70.642 
2 1 3 41.58900 -71.281 
3 1 3 37.64900 -71.440 
4 2 2 18.46200 -66.103 
5 2 2 18.44857 -66.089 
6 2 2 42.24200 -70.970 
+0

Vielen Dank, das ist fast was ich will, aber am Ende sollte die Ausgabe df etwas anders sein. Der Ausgang df enthält nur die Punkte, die angepasst wurden, ich möchte die gesamte Trajektorie, so wie es eine Übereinstimmung in Zeile 4 in df1 gibt, so dass die Trajektorie von unserer spezifizierten Region ausgeht, jetzt sollte das ** final df ** sein enthalten alle Punkte aus Zeile 4 7 zu Zeile, die durch Reihen gefolgt 9 bis 11, weil es 11. – Liza

+0

@Liza in Reihe ein Spiel hatte, Antwort die i aktualisiert haben - überprüfen Sie bitte – MaxU

+0

Dieses ist perfekt, danke sooooooo viel. – Liza

Verwandte Themen