2017-02-11 3 views
1

Ich habe einen Datenrahmen von Menschen und Jahren weiter ausbauen beschäftigt:Pandas: Datenrahmen zeilenweise, ähnlich wie R SurvSplit()

person_id years     
1   1.00 
2   2.34 
3   6.85 

Ich möchte auf vordefinierte „Chunks die Datenrahmen zeilenweise Basis erweitern "in der Amtszeit des Arbeitnehmers. Zum Beispiel, wenn ich bei der 1 Jahr-Marke chunk Menschen Amtszeit will, würden die oben Datenrahmen werden:

person_id tstart tend     
1   0.00 1.00 
2   0.00 1.00 
2   1.00 2.34 
3   0.00 1.00 
3   1.00 6.85 

Wenn ich Brocken auf 1 Jahr und 2 yr Marke wollte, wird der ursprüngliche Datenrahmen:

person_id tstart tend     
1   0.00 1.00 
2   0.00 1.00 
2   1.00 2.00 
2   2.00 2.34 
3   0.00 1.00 
3   1.00 2.00 
3   2.00 6.85 

also ideal, ich möchte eine list oder tuple von Brocken, um die reihenweise Expansion zu lenken (zB [1,2] in Jahren chunk 1 und 2)

Diese Datenrahmen Manipulationbis R ähnlich sein würde- siehe S. 127 here

Wie kann ich das tun? Ich habe ein paar Artikel über Stackoverflow gefunden, aber sie diskutieren verschiedene Ziele für die Erweiterung von Datenrahmen.

Antwort

1

Betrachten Sie die folgende definierte Methode. Obwohl ein bisschen ein Freilos es keine Schleifen im Gegensatz zu survsplit eigentlichen Quellcode verwendet, die in C geschrieben wird

Unten im Wesentlichen läuft ein Kreuz iterative tenure Jahren beitreten zu max von Brocken arg und geht bis zu dem Punkt Personen Jahre. Dann werden ursprüngliche Datenrahmenwerte mit berechneten tstart und tend Spalten auf dem merge Ergebnis verkettet. Ein Schlüssel zur Originaldatenrahmen zugeordnet werden müssen, hier Personen sein:

from io import StringIO 
import pandas as pd 
import numpy as np 

persons = pd.read_table(StringIO("""person_id years     
1   1.00 
2   2.34 
3   6.85"""), sep="\s+").assign(key = 1) 

def expand_tenure(chunk): 
    newpersons = persons.assign(tstart = chunk, tend = persons['years']) 
    newpersons.loc[newpersons['tend'] < chunk, 'tstart'] = np.floor(persons['years']) 

    df = pd.DataFrame({'tstart': list(range(0, chunk)), 
         'tend': list(range(1, chunk+1)), 
         'key': 1}) 

    mdf = pd.merge(persons, df, on='key')  
    mdf = mdf[mdf['tend'] <= mdf['years']][['person_id', 'tstart', 'tend']] 

    cdf = pd.concat([newpersons[['person_id', 'tstart', 'tend']], mdf])\ 
        .sort_values(['person_id', 'tstart'])\ 
        .drop_duplicates(['person_id', 'tend']).reset_index(drop=True) 

    return cdf 

Output(drei Läufe)

print(expand_tenure(1)) 
# person_id tstart tend 
# 0   1  0.0 1.00 
# 1   2  0.0 1.00 
# 2   2  1.0 2.34 
# 3   3  0.0 1.00 
# 4   3  1.0 6.85 

print(expand_tenure(4)) 
# person_id tstart tend 
# 0   1  0.0 1.00 
# 1   2  0.0 1.00 
# 2   2  1.0 2.00 
# 3   2  2.0 2.34 
# 4   3  0.0 1.00 
# 5   3  1.0 2.00 
# 6   3  2.0 3.00 
# 7   3  3.0 4.00 
# 8   3  4.0 6.85 

print(expand_tenure(12)) 
#  person_id tstart tend 
# 0   1  0.0 1.00 
# 1   2  0.0 1.00 
# 2   2  1.0 2.00 
# 3   2  2.0 2.34 
# 4   3  0.0 1.00 
# 5   3  1.0 2.00 
# 6   3  2.0 3.00 
# 7   3  3.0 4.00 
# 8   3  4.0 5.00 
# 9   3  5.0 6.00 
# 10   3  6.0 6.85 
+0

Awesome, danke! – NickBraunagel