2016-07-07 15 views
3

私はこの種のパンダのDataFrameを大規模なデータベースの各ユーザに持っています。スパースdatetimeindexからの範囲を取得

enter image description here

各行は長さの期間である[START_DATE、END_DATE]、時には2つの連続した行は、実際には同じ期間である:end_dateは以下start_date(赤下線)に等しいです。場合によっては期間が1日以上重複することもあります。

私は、同じ期間に対応する行を組み合わせることによって「実期間」を得たいと考えています。

私は各colunms期間であるデータフレーム生じる

def split_range(name): 
    df_user = de_201512_echant[de_201512_echant.name == name] 
    # -- Create a date_range with a length [min_start_date, max_start_date] 
    t_date = pd.DataFrame(index=pd.date_range("2005-01-01", "2015-12-12").date) 
    for row in range(0, df_user.shape[0]): 
     start_date = df_user.iloc[row].start_date 
     end_date = df_user.iloc[row].end_date 
     if ((pd.isnull(start_date) == False) and (pd.isnull(end_date) == False)): 
      t = pd.DataFrame(index=pd.date_range(start_date, end_date)) 
      t["period_%s" % (row)] = 1 
      t_date = pd.merge(t_date, t, right_index=True, left_index=True, how="left") 
     else: 
      pass 

    return t_date 

試みた(範囲内の場合は1を、NaNでない場合):

t_date 
Out[29]: 
      period_0 period_1 period_2 period_3 period_4 period_5 \ 
2005-01-01  NaN  NaN  NaN  NaN  NaN  NaN 
2005-01-02  NaN  NaN  NaN  NaN  NaN  NaN 
2005-01-03  NaN  NaN  NaN  NaN  NaN  NaN 
2005-01-04  NaN  NaN  NaN  NaN  NaN  NaN 
2005-01-05  NaN  NaN  NaN  NaN  NaN  NaN 
2005-01-06  NaN  NaN  NaN  NaN  NaN  NaN 
2005-01-07  NaN  NaN  NaN  NaN  NaN  NaN 
2005-01-08  NaN  NaN  NaN  NaN  NaN  NaN 
2005-01-09  NaN  NaN  NaN  NaN  NaN  NaN 
2005-01-10  NaN  NaN  NaN  NaN  NaN  NaN 
2005-01-11  NaN  NaN  NaN  NaN  NaN  NaN 

そしてI和ならすべての列(ピリオド)は、私が望むものをほぼ正確に得ます:

full_spell = t_date.sum(axis=1) 
full_spell.loc[full_spell == 1] 

Out[31]: 
2005-11-14 1.0 
2005-11-15 1.0 
2005-11-16 1.0 
2005-11-17 1.0 
2005-11-18 1.0 
2005-11-19 1.0 
2005-11-20 1.0 
2005-11-21 1.0 
2005-11-22 1.0 
2005-11-23 1.0 
2005-11-24 1.0 
2005-11-25 1.0 
2005-11-26 1.0 
2005-11-27 1.0 
2005-11-28 1.0 
2005-11-29 1.0 
2005-11-30 1.0 
2006-01-16 1.0 
2006-01-17 1.0 
2006-01-18 1.0 
2006-01-19 1.0 
2006-01-20 1.0 
2006-01-21 1.0 
2006-01-22 1.0 
2006-01-23 1.0 
2006-01-24 1.0 
2006-01-25 1.0 
2006-01-26 1.0 
2006-01-27 1.0 
2006-01-28 1.0 

2015-07-06 1.0 
2015-07-07 1.0 
2015-07-08 1.0 
2015-07-09 1.0 
2015-07-10 1.0 
2015-07-11 1.0 
2015-07-12 1.0 
2015-07-13 1.0 
2015-07-14 1.0 
2015-07-15 1.0 
2015-07-16 1.0 
2015-07-17 1.0 
2015-07-18 1.0 
2015-07-19 1.0 
2015-08-02 1.0 
2015-08-03 1.0 
2015-08-04 1.0 
2015-08-05 1.0 
2015-08-06 1.0 
2015-08-07 1.0 
2015-08-08 1.0 
2015-08-09 1.0 
2015-08-10 1.0 
2015-08-11 1.0 
2015-08-12 1.0 
2015-08-13 1.0 
2015-08-14 1.0 
2015-08-15 1.0 
2015-08-16 1.0 
2015-08-17 1.0 
dtype: float64 

しかし、私は最終的に私の希望する出力を得るために、この疎な日時インデックスのすべての時間範囲をスライスする方法を見つけることができませんでした: "本物の"期間を含む元のデータフレーム。

これを行うのが最も効率的な方法ではない可能性があります。代替手段があれば、躊躇しないでください!

答えて

0

私はapplyを使用してこれを行うには、はるかに効率的な方法を見つけました:

def get_range(row): 
    '''returns a DataFrame containing the day-range from a "start_date" 
    and a "end_date"''' 
    start_date = row["start_date"] 
    end_date = row["end_date"] 
    period = pd.date_range(start_date, end_date, freq="1D") 

    return pd.Dataframe(period, columns='days_in_period') 

# -- Apply get_range() to the initial df 
t_all = df.apply(get_range) 
# -- Drop overlapping dates 
t_all.drop_duplicates(inplace=True) 
関連する問題