2017-11-27 1 views
0

Angenommen, ich habe zwei Richtliniendaten wie unten.So extrahieren und zählen Sie in bestimmten Bedingungen in Python

enroll lapse 
A 2010/2/1 2013/1/2 
B 2012/3/1 2013/1/4 

Ich möchte die Anzahl, die Richtlinien zu Beginn des Jahres dauern, zählen.

enroll lapse  year 
A 2010/2/1 2013/1/2 2011/1/1 
A 2010/2/1 2013/1/2 2012/1/1 
A 2010/2/1 2013/1/2 2013/1/1 
B 2012/3/1 2013/1/4 2013/1/1 

und zählen Sie diese laufenden Richtlinien.

year num 
2011 1 
2012 1 
2013 2 

Ich denke, ich muss Abfrage-Methode verwenden. aber ich konnte es nicht herausfinden.

+0

diese Daten aus Datenbanktabelle verwenden oder welches Format ist? – iamnewuser

+0

in welchem ​​Datumsformat ist "2012/1/4" nach "2012/3/1"? –

+0

Entschuldigung Datenformat ist Datetime! – Heisenberg

Antwort

1

Sie benötigen:

#convert columns to datetimes 
df['enroll'] = pd.to_datetime(df['enroll']) 
df['lapse'] = pd.to_datetime(df['lapse']) 

Für jede Zeile Funktion gilt für die Zeilen erweitern, um die Serie neu zu gestalten und zu ursprünglichen df verbinden:

def f(x): 
    b = x['lapse'].year - x['enroll'].year 
    return (pd.Series(pd.date_range(x['enroll'], periods=b, freq='AS'))) 

s = df.apply(f, axis=1).stack().reset_index(level=1, drop=True).rename('year') 

df = df.join(s) 
print (df) 
     enroll  lapse  year 
A 2010-02-01 2013-01-02 2011-01-01 
A 2010-02-01 2013-01-02 2012-01-01 
A 2010-02-01 2013-01-02 2013-01-01 
B 2012-03-01 2013-01-04 2013-01-01 

Einem anderen Lösung:

#create start year 
df['year'] = df['enroll'] + pd.offsets.YearBegin(0) 
#count repeating 
a = df['lapse'].dt.year - df['enroll'].dt.year 
df = df.loc[np.repeat(df.index, a)] 
#add year offset 
df['a'] = df.groupby(level=0).cumcount() 
df["year"] = df.apply(lambda x: x["year"] + pd.offsets.DateOffset(years=x['a']), axis=1) 
df = df.drop('a', 1) 
print (df) 
     enroll  lapse  year 
A 2010-02-01 2013-01-02 2011-01-01 
A 2010-02-01 2013-01-02 2012-01-01 
A 2010-02-01 2013-01-02 2013-01-01 
B 2012-03-01 2013-01-04 2013-01-01 

Und zuletzt:

+0

Habe ich die Frage missverstanden? Dies scheint eine komplizierte Antwort zu sein. –

+0

Es scheint ja, leider :( – jezrael

+0

Fair genug ... Antwort wurde entfernt. –

1

Lesen Sie zuerst Ihre Richtliniendaten Zeile für Zeile.

enroll lapse 
A 2010/2/1 2013/1/2 
B 2012/3/1 2012/1/4 

und dann jede Zeile in die Funktionsanzahl eingeben.
Wörterbuch Ergebnis könnte das gewünschte sein?
Wenn es ein Missverständnis Ihrer Frage gibt, lassen Sie es mich bitte wissen.

result = {} 
def count(start, end): 
    start = [int(i) for i in start.split('/')] 
    start = datetime.date(*start) 
    end = [int(i) for i in end.split('/')] 
    end = datetime.date(*end) 
    delta = end - start 
    new = start + datetime.timedelta(delta.days) 
    for i in range(1, new.year - start.year + 1): 
     result[start.year + i] = result.setdefault(start.year + i, 0) + 1 


a = count('2010/2/1', '2013/1/2') 
b = count('2012/3/1', '2013/1/4') 
1

können Sie pd.daterange

start = pd.Timestamp(year=df['enroll'].dt.year.min() + 1, month=1, day=1) 
end = pd.Timestamp(year=df['lapse'].dt.year.max(), month=12, day=31) 

for year in pd.date_range(start=start, end=end, freq='AS'): 
    print(year, ((df['enroll'] < year) & (df['lapse'] > year)).sum()) 
2011-01-01 00:00:00 1 
2012-01-01 00:00:00 1 
2013-01-01 00:00:00 2 
data = {year.year: ((df['enroll'] < year) & (df['lapse'] > year)).sum() for year in pd.date_range(start=start, end=end, freq='AS')} 
pd.Series(data) 
2011 1 
2012 1 
2013 2 
dtype: int64 
Verwandte Themen