2016-04-05 8 views
5

ich eine pandas.DataFrame der Form habenClassify Daten von Wert in Pandas

low_bound high_bound name 
0   10   'a' 
10   20   'b' 
20   30   'c' 
30   40   'd' 
40   50   'e' 

Ich habe ein sehr langepandas.Series der Form:

value 
5.7 
30.4 
21 
35.1 

ich jeden Wert geben wollen von die Serie ihren entsprechenden Namen in Bezug auf den Low_Bound/High_Bound/Name DataFrame. Hier ist mein angestrebtes Ergebnis:

value   name 
5.7   'a' 
30.4   'd' 
21   'c' 
35.1   'd' 

Tat 5.7 Name ist 'a' seit 5.7 zwischen 0 und 10 ausgeschlossen.

Was wäre der effizienteste Code? Ich weiß, dass ich das Problem lösen kann, indem ich durch die Serie iteriere, aber vielleicht gibt es eine schnellere vektorielle Lösung, die mir entgeht.

Beachten Sie schließlich, dass meine Grenzen benutzerdefinierte und unregelmäßige sein können. Hier sind sie regelmäßig für das Beispiel.

Antwort

4

Pandas hat eine Methode cut genannt, die das tun, was Sie wollen:

import pandas as pd 

data = [{"low": 0, "high": 10, "name": "a"}, 
     {"low": 10, "high": 20, "name": "b"}, 
     {"low": 20, "high": 30, "name": "c"}, 
     {"low": 30, "high": 40, "name": "d"}, 
     {"low": 40, "high": 50, "name": "e"},] 

myDF = pd.DataFrame(data) 

#data to be binned 
mySeries = pd.Series([5.7, 30.4, 21, 35.1]) 

#create bins from original data 
bins = list(myDF["high"]) 
bins.insert(0,0) 

print pd.cut(mySeries, bins, labels = myDF["name"]) 

Das gibt Ihnen die folgende, die Sie dann wieder in einem gewissen Datenrahmen setzen können oder aber Sie möchten, dass Ihre Daten halten:

Je nachdem, wie unregelmäßig Ihre Bins sind (und was Sie genau mit custom/irregular meinen), müssen Sie möglicherweise auf das Durchlaufen der Serie zurückgreifen. Ich kann nicht über die Spitze meines Kopfes eines Built-in denken, der das für Sie handhaben wird, besonders abhängig davon, dass es vom Grad/Typ der Unregelmäßigkeit in den Behältern abhängt.

Looping weise, diese Methode funktioniert, wenn Sie eine untere und obere Schranke, unabhängig von „Regelmäßigkeit“:

for el in mySeries: 
    print myDF["name"][(myDF["low"] < el) & (myDF["high"] > el)] 

Ich schätze, dass Sie nicht in einer Schleife durch eine riesige Serie wollen könnte, aber zumindest wir indizieren nicht manuell in den Datenrahmen, was die Dinge wahrscheinlich noch langsamer machen würde