2016-04-22 3 views
1

Ich habe eine DataFramedf:Chaining Betreiber Wert zu ermitteln, wo Datensatz am nächsten zu einer Zahl ist

id Volume time_norm time_norm_ratio speed BPR_free_speed free_flow_speed capacity_speed dev_free_flow 
9SOUTHBOUND 1474 85 1.794392523 8.947916667 17.88 16.05607477 8.028037383 0.919879283 
9SOUTHBOUND 1375 17 1.158878505 13.85483871 17.88 16.05607477 8.028037383 5.826801327 
9SOUTHBOUND 1052 22 1.205607477 13.31782946 17.88 16.05607477 8.028037383 5.289792074 
9SOUTHBOUND 986 21 1.196261682 13.421875 17.88 16.05607477 8.028037383 5.393837617 
9SOUTHBOUND 1071 15 1.140186916 14.08196721 17.88 16.05607477 8.028037383 6.05392983 
9SOUTHBOUND 1206 34 1.317757009 12.18439716 17.88 16.05607477 8.028037383 4.15635978 
9SOUTHBOUND 1222 34 1.317757009 12.18439716 17.88 16.05607477 8.028037383 4.15635978 
9SOUTHBOUND 1408 33 1.308411215 12.27142857 17.88 16.05607477 8.028037383 4.243391188 
9SOUTHBOUND 1604 69 1.644859813 9.761363636 17.88 16.05607477 8.028037383 1.733326253 
9SOUTHBOUND 1731 124 2.158878505 7.437229437 17.88 16.05607477 8.028037383 -0.590807946 
9SOUTHBOUND 1596 640 6.981308411 2.299866131 17.88 16.05607477 8.028037383 -5.728171252 
9NORTHBOUND 449 17 1.17 14.66666667 17.88 17.16 8.58 6.086666667 
9NORTHBOUND 299 17 1.17 14.66666667 17.88 17.16 8.58 6.086666667 
9NORTHBOUND 241 18 1.18 14.54237288 17.88 17.16 8.58 5.962372881 
9NORTHBOUND 164 13 1.13 15.18584071 17.88 17.16 8.58 6.605840708 
9NORTHBOUND 142 16 1.16 14.79310345 17.88 17.16 8.58 6.213103448 
9NORTHBOUND 137 15 1.15 14.92173913 17.88 17.16 8.58 6.34173913 
9NORTHBOUND 196 13 1.13 15.18584071 17.88 17.16 8.58 6.605840708 

Ich wünsche die volume zu finden, wenn die Geschwindigkeit für jeden id 50% der maximalen Geschwindigkeit. Um dies zu tun, fand ich die maximale Geschwindigkeit (free_flow_speed) pro ID, berechnet 50% davon und setze es auf free_flow_speed. Um festzustellen, welcher Datensatz dem 50% free_flow_speed am nächsten kommt, habe ich eine dev_free_flow Spalte erstellt, die den Unterschied zwischen dem angegebenen speed und dem free_flow_speed darstellt. Suchen Sie nach dem Datensatz, der dem Wert 0 am nächsten ist, und geben Sie für jeden id den Datensatz an, für den der cap_design-Wert zugewiesen werden soll.

Deshalb möchte ich cap_design eine neue Spalte erstellen, die die volume ist, wenn diff am nächsten Null ist, für jede id.

Aus meiner letzten Frage SO (Ich bin nicht einen guten Tag hier) Ich habe erstellt:

df['cap_design'] = df['Volume'].where(df.groupby('id')['diff'].transform('min')) 

Doch diese gibt einen cap_design Wert der Volume pro dieser Reihe, eher als das Volumen der der am nächsten zu Null liegende Wert für dev_free_flow, per id. Wie erreiche ich das?

Antwort

2

Mit pd.Series.searchsorted(), können Sie den Index erhalten, in dem Sie einen bestimmten Wert in einer sortierten Series einsetzen sollen, um (50% der Series.max(), in Ihrem Fall) zu erhalten, die Sie dann den entsprechenden Wert in einer anderen Serie verwenden können, um zu wählen (Volume). Also, mit was die relevante Teilmenge der Daten zu sein scheint:

   id Volume  speed 
13 9NORTHBOUND  241 14.542373 
11 9NORTHBOUND  449 14.666667 
12 9NORTHBOUND  299 14.666667 
15 9NORTHBOUND  142 14.793103 
16 9NORTHBOUND  137 14.921739 
14 9NORTHBOUND  164 15.185841 
17 9NORTHBOUND  196 15.185841 
10 9SOUTHBOUND 1596 2.299866 
9 9SOUTHBOUND 1731 7.437229 
0 9SOUTHBOUND 1474 8.947917 
8 9SOUTHBOUND 1604 9.761364 
5 9SOUTHBOUND 1206 12.184397 
6 9SOUTHBOUND 1222 12.184397 
7 9SOUTHBOUND 1408 12.271429 
2 9SOUTHBOUND 1052 13.317829 
3 9SOUTHBOUND  986 13.421875 
1 9SOUTHBOUND 1375 13.854839 
4 9SOUTHBOUND 1071 14.081967 

Verwendung:

df = df.sort_values(['id', 'speed']) 
df.groupby('id').apply(lambda x: x.Volume.iloc[x.speed.searchsorted(x.speed.max()*.5)]) 

zu erhalten:

9NORTHBOUND 13  241 
9SOUTHBOUND 9  1731 
Name: Volume, dtype: int64 

Wenn Sie das Ergebnis als neue Spalte möchten, Sie könnten tun:

df['result'] = df.groupby('id', as_index=False).apply(lambda x: pd.Series(x.Volume.iloc[x.speed.searchsorted(x.speed.max()/2)].tolist() * len(x),index=x.index)).reset_index(level=0, drop=True) 

df.loc[:, ['id', 'Volume', 'speed', 'result']] 

      id Volume  speed result 
0 9NORTHBOUND  241 14.542373  241 
1 9NORTHBOUND  449 14.666667  241 
2 9NORTHBOUND  299 14.666667  241 
3 9NORTHBOUND  142 14.793103  241 
4 9NORTHBOUND  137 14.921739  241 
5 9NORTHBOUND  164 15.185841  241 
6 9NORTHBOUND  196 15.185841  241 
7 9SOUTHBOUND 1596 2.299866 1731 
8 9SOUTHBOUND 1731 7.437229 1731 
9 9SOUTHBOUND 1474 8.947917 1731 
10 9SOUTHBOUND 1604 9.761364 1731 
11 9SOUTHBOUND 1206 12.184397 1731 
12 9SOUTHBOUND 1222 12.184397 1731 
13 9SOUTHBOUND 1408 12.271429 1731 
14 9SOUTHBOUND 1052 13.317829 1731 
15 9SOUTHBOUND  986 13.421875 1731 
16 9SOUTHBOUND 1375 13.854839 1731 
17 9SOUTHBOUND 1071 14.081967 1731 
Verwandte Themen