2017-11-29 9 views
-1

: 내가 쓴파이썬 팬더 : 벡터화 된 시계열 윈도우 함수 나는 다음과 같은 형식의 팬더 dataframe이

'customer_id','transaction_dt','product','price','units' 
1,2004-01-02,thing1,25,47 
1,2004-01-17,thing2,150,8 
2,2004-01-29,thing2,150,25 
3,2017-07-15,thing3,55,17 
3,2016-05-12,thing3,55,47 
4,2012-02-23,thing2,150,22 
4,2009-10-10,thing1,25,12 
4,2014-04-04,thing2,150,2 
5,2008-07-09,thing2,150,43 

을 30 일 개 창을 나타내는 두 개의 새로운 필드를 만들려면 다음

import numpy as np 
import pandas as pd 

start_date_period = pd.period_range('2004-01-01', '12-31-2017', freq='30D') 
end_date_period = pd.period_range('2004-01-30', '12-31-2017', freq='30D') 

def find_window_start_date(x): 
    window_start_date_idx = np.argmax(x < start_date_period.end_time) 
    return start_date_period[window_start_date_idx] 

df['window_start_dt'] = df['transaction_dt'].apply(find_window_start_date) 

def find_window_end_date(x): 
    window_end_date_idx = np.argmin(x > end_date_period.start_time) 
    return end_date_period[window_end_date_idx] 

df['window_end_dt'] = df['transaction_dt'].apply(find_window_end_date) 

을 불행히도 이것은 응용 프로그램에 행렬 방식으로 적용하는 것은 너무 느립니다. 가능한 경우 이러한 기능을 벡터 라이 제이션하는 데 대한 모든 정보를 매우 감사하겠습니다.

편집 :

'customer_id','transaction_dt','product','price','units','window_start_dt','window_end_dt' 

그것은 다시 샘플링하거나 형식적인 의미에서, 윈도우를 할 필요가 없습니다 : 결과의 dataframe이 레이아웃을 가지고 있어야

. 'window_start_dt'및 'window_end_dt'열을 추가하면됩니다. 현재 코드가 작동하면 가능한 경우 벡터화해야합니다.

+0

확인하기 만하면 30 일짜리 창에 속하는 마지막 날짜 (데이터에 나타나는 날짜) 만 추출하려는 것입니까? –

+0

@AntoineZambelli 나는 당신이 무엇을 의미하는지 생각합니다. 사실 groupby 작업을 추가로 수행 할 필요가 없으므로 Windows에서 처음/마지막 날짜를 선택할 필요가 없습니다. 기존 행에 적용하기 만하면됩니다. 내가 오해하면 사과드립니다. – Pylander

+0

좋아, 잘하면 나는 그것을 올바르게 이해하고, 나는 당신이'resample'을 원한다고 생각한다! –

답변

0

편집 2 : pandas.cut가 내장되어 있습니다 :

tt=[[1,'2004-01-02',0.1,25,47], 
[1,'2004-01-17',0.2,150,8], 
[2,'2004-01-29',0.2,150,25], 
[3,'2017-07-15',0.3,55,17], 
[3,'2016-05-12',0.3,55,47], 
[4,'2012-02-23',0.2,150,22], 
[4,'2009-10-10',0.1,25,12], 
[4,'2014-04-04',0.2,150,2], 
[5,'2008-07-09',0.2,150,43]] 



start_date_period = pd.date_range('2004-01-01', '12-01-2017', freq='MS') 
end_date_period = pd.date_range('2004-01-30', '12-31-2017', freq='M') 

df = pd.DataFrame(tt,columns=['customer_id','transaction_dt','product','price','units']) 
df['transaction_dt'] = pd.Series([pd.to_datetime(sub_t[1],format='%Y-%m-%d') for sub_t in tt]) 

the_cut = pd.cut(df['transaction_dt'],bins=start_date_period,right=True,labels=False,include_lowest=True) 

df['win_start_test'] = pd.Series([start_date_period[int(x)] if not np.isnan(x) else 0 for x in the_cut]) 
df['win_end_test'] = pd.Series([end_date_period[int(x)] if not np.isnan(x) else 0 for x in the_cut]) 

print(df.head()) 

win_start_testwin_end_test 그들의 대응과 동일 함수를 사용하여 계산한다.

ValueError은 해당 라인의 x에서 int으로 전송되지 않았습니다. 또한이 장난감 예제에는 필요하지 않지만 NaN 수표를 추가했습니다.

pd.date_range의 변화와 및 월말 플래그 시작 개월의 MMS의 사용뿐만 아니라 datetime에 날짜 문자열 변환.

+0

고마워요.하지만이게 내가 원하는 것 같지는 않습니다. 달력 날짜에 연결되지 않고 정의한 임의의 창을 사용할 수 있기를 원합니다. 이 창들이 서로 인접 해 있다는 보장이 없습니다. – Pylander

+0

임의의 윈도우가 달력 날짜에 연결되어 있지 않다면 나는 정말로 혼란스러워합니다. 아마도 예상 출력을 게시 할 수 있습니까? 'resample'은 연속되지 않는 데이터와 함께 작동한다고 생각합니다 (정렬 만하면됩니다). 어쩌면 당신이 '압연'을 원할 것 같습니까? –

+0

몇 가지 설명을 추가했습니다. groupby 유형의 계산을 시작하기 전에 결과 데이터를 여러 데이터 소스와 병합해야하기 때문에 적용된 창 날짜 만 있으면되고 다른 것은 변경되지 않습니다. 리샘플링/롤링하면 조기에 변환/집계를 수행 할 것입니다. – Pylander

관련 문제