2017-05-22 3 views
0

Ich habe tägliche Daten und eine Schleife, die jeden dritten Freitag in einem Monat definiert und ändert dann den Wert einer Spalte auf 2 für die 20 Tage von und zu diesem dritten Freitag. Die Markierung funktioniert jedoch nur für die Tage NACH dem dritten Freitag davor. Ich verstehe nicht warum. My Datenrahmen „verschmolzen“ ist folgende:Pandas: Subtraktion Timedelta in Schleife

Date   ID Window 
01/01/2000 1  0 
01/01/2000 1  0 
02/01/2000 2  0 
02/01/2000 2  0 

Der Code so weit ist die folgende:

#Get third friday in a month Friday: 

c = calendar.Calendar(firstweekday=calendar.SUNDAY) 
year = 2000; month = 3 
monthcal = c.monthdatescalendar(year,month) 
third_friday = [day for week in monthcal for day in week if \ 
      day.weekday() == calendar.FRIDAY and \ 
      day.month == month][2] 

#Loop through dates to change the window column: 

for beg in pd.date_range("2000-01-01", "2017-05-01"): 
    beg= third_friday 
     merged["window"].loc[beg: beg + pd.to_timedelta(20,"D")] = 2 
     merged["window"].loc[beg: beg - pd.to_timedelta(20,"D")] = 2 

#repeat the same for the next Fridays: 
    if month==12: 
     year=year+1 
     month=0 
    if year>=2017 and month>=3: 
     break 
    month = month +3 
    monthcal = c.monthdatescalendar(year,month) 
    third_friday = [day for week in monthcal for day in week if \ 
       day.weekday() == calendar.FRIDAY and \ 
       day.month == month][2] 

Wenn ich diesen Code ausführen, ich habe nicht die Fenster Spalte 2 vor dem dritten bekommen Freitag. Nur die Tage 20 Tage nach dem dritten Freitag werden auf 2 geändert. Weiß jemand, was mache ich falsch?

+0

Sie wissen, dass diese 20 Tage vor und nach Perioden überlappen –

+0

Aber anscheinend tun Sie nur das alle 3 Monate, nicht jeden Monat, so ignorieren, was ich oben sagte –

Antwort

1

dritter Freitag des Monats

am einfachsten wäre es, eine Methode zu definieren 3. Freitag des Monats zu berechnen, ein Jahr und Monat gegeben. Verwenden Sie entweder Ihre Methode mit calendar, oder so etwas wie dies funktionieren könnte auch

def third_friday_of(year, month): 
    pd.DatetimeIndex(start = '%i/%i/15' % (year, month,), end='%i/%i/21' % (year, month,), freq='d') 
    return daterange[daterange.weekday == 4][0] 

dies gibt einen pandas.Timestamp, aber das ist eine Unterklasse von datetime.datetime, so sollten keine weiteren Probleme in Ihrem Programm

Tatsächliche Berechnungen stellen

I definiert auch ein separates Verfahren die tatsächliche Änderung des DataFrame, mit dem Intervall und Fenster zu tun, wie

def process_dataframe(df, begin_year, begin_month, end_year, end_month, interval_months=3, window=20): 
    end_month = min(end_month + 1, 12) 
    dates = pd.DatetimeIndex(start = '%i/%i' % (begin_year, begin_month,), end='%i/%i' % (end_year, end_month), freq='%im' % interval_months) 
    for d in dates: 
     third_friday = third_friday_of(d.year, d.month) 
#   print(d, third_friday) 
     df.loc[third_friday - pd.Timedelta(window, unit='d') : third_friday 2 pd.Timedelta(window, unit='d'), 'Window'] = 2 
Parameter

Der Grund, es nicht funktioniert hätte für Sie wurde merged["window"].loc[beg: beg - pd.to_timedelta(20,"D")] = 2merged["window"].loc[beg - pd.to_timedelta(20,"D"):beg] = 2

Chained Zuordnung

merged["window"].loc[beg: beg + pd.to_timedelta(20,"D")] = 2 an sich gewesen sein sollte hat ein zweites Problem. Mit merged["window"] fragen Sie nach einer Serie, aber es ist nicht 100% klar oder deterministisch, ob Sie eine Ansicht oder eine Kopie erhalten. Besser ist es, dies in 1 .loc wie in meinem Code

Verwandte Themen