2016-06-16 3 views
2

나는 다음과 같은 dataframe 있습니다계산 낮 시간의 차이 Dataframe

data = [ 
("10/10/2016","A"), 
("10/10/2016","B"), 
("09/12/2016","B"), 
("09/12/2016","A"), 
("08/11/2016","A"), 
("08/11/2016","C")] 

#Create DataFrame base 
df = pd.DataFrame(data, columns=("Time","User")) 

# Convert time column to correct format for time calculations 
df["Time"] = pd.to_datetime(df["Time"], '%m/%d/%Y') 

사용자가 특정 작업을 할 때 각 행을 나타냅니다. 얼마나 자주 (일 기준) 사용자가 특정 작업을 수행할지 계산하고 싶습니다.

사용자 A는 2011 년 8 월 11 일에 처음으로 거래를 한 다음 2014 년 9 월 12 일에 다시 거래를 시작한 지 약 30 일 후를 가정 해 보겠습니다. 그 다음, 그는 두 번째 거래 후 약 29 일 후인 10/10/2016에 다시 거래했습니다. 따라서 그의 평균 빈도는 (29 + 30)/2 일입니다.

가장 효율적인 방법은 무엇입니까?

미리 감사드립니다.



  • 업데이트 내 원하는 출력을 계산 다음 함수를 썼다.

    from datetime import timedelta 
    
    def averagetime(a): 
        numdeltas = len(a) - 1 
        sumdeltas = 0 
    
        i = 1 
        while i < len(a): 
         delta = abs((a[i] - a[i-1]).days) 
         sumdeltas += delta 
         i += 1 
    
        if numdeltas > 1: 
         avg = sumdeltas/numdeltas 
        else: 
         avg = 'NaN' 
        return avg 
    

    내가 온 "시간"열을 전달할 때, 예를 들어, 올바르게 작동 :

    averagetime(df["Time"]) 
    

    을하지만별로 그룹화 한 후 적용 할 때 그것은 나에게 오류를 제공합니다.

    df.groupby('User')['Time'].apply(averagetime) 
    

    위의 사항을 어떻게 해결할 수 있습니까?

+0

하지 정확한 대답, 그러나 아마 당신 google [pairwise difference] (https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0ahUKEwiohv3d5KvNAhVU0WMKHYHWCR0QFggeMAA&url=http%3A%2F%2Fstackoverflow.com%2Fquestions%2F21467429%)를 시도해보십시오. 2 대각선 매트릭스 - 대 - 판다 - 데이터 프레임 & usg = AFQjCNG1vrKJgkLxfWwiCwHyDRTzG1aevA & sig2 = 1qi6JGBnoqNr7UFuT_3xPw) – hd1

+0

DD 원하는 출력? – jezrael

답변

1

당신은 np.timedelta64(1,'D')에 의해 abssumfloat로 변환 diff을 사용할 수 있습니다,

print (averagetime(df["Time"])) 
12.0 

su = ((df["Time"].diff()/np.timedelta64(1,'D')).abs().sum()) 
print (su/(len(df) - 1)) 
12.0 

가 그럼 난 groupby에 적용하지만, 필요 조건이 있기 때문에 :

ZeroDivisionError: float division by zero

print (df.groupby('User')['Time'] 
     .apply(lambda x: np.nan if len(x) == 1 
           else (x.diff()/np.timedelta64(1,'D')).abs().sum()/(len(x)-1))) 

User 
A 30.0 
B 28.0 
C  NaN 
Name: Time, dtype: float64 
+0

답을 수정합니다. 확인해주세요. – jezrael

+0

그레이트 솔루션! 정말 고맙습니다! – morfara

0

@ Jezrael의 대답에서 시작하기 :

-에 의한 경우

는 "얼마나 자주"당신 말은 얼마나 많은 시간 것은 여기에서 다음 작업을 수행하는 각 사용자 사이를 통과 접근법이다 :

import pandas as pd 
import numpy as np 

data = [ 
    ("10/10/2016","A"), 
    ("10/10/2016","B"), 
    ("09/12/2016","B"), 
    ("09/12/2016","A"), 
    ("08/11/2016","A"), 
    ("08/11/2016","C"), 
] 

# Create DataFrame base 
df = pd.DataFrame(data, columns=("Time","User")) 

# Convert time column to correct format for time calculations 
df["Time"] = pd.to_datetime(df["Time"], dayfirst=True) 

# Group the DF by min, max and count the number of instances 
grouped = (df.groupby("User").agg([np.max, np.min, np.count_nonzero]) 

      # This step is a bit messy and could be improved, 
      # but we need the count as an int 
      .assign(counter=lambda x: x["Time"]["count_nonzero"].astype(int)) 

      # Use apply to calculate the time between first and last, then divide by frequency 
      .apply(lambda x: (x["Time"]["amax"] - x["Time"]["amin"])/x["counter"].astype(int), axis=1) 
      ) 

# Output the DF if using an interactive prompt 
grouped 

출력 :

User  
A 20 days 
B 30 days 
C 0 days