2017-04-07 83 views
3

我想計算一組使用熊貓的人的週轉率。該組的規模可能會發生變化,但我想知道每年離開的人數百分比。熊貓:如何計算週轉率?

用一個例子更好地解釋。這裏是我的樣本數據:

teachers year 
0  John 2007 
1  Paul 2007 
2  Mary 2007 

3  John 2008 
4  Paul 2008 
5  Abel 2008 
6  Watt 2008 

7  John 2009 
8  Mary 2009 

我想在此數據集到達:

year turnover 
2008 .33333 
2009 .75 

在第一年,瑪麗離開了,在第二年的保羅,亞伯和瓦離開。它會有一些偏見:如果這個組織縮小了,那麼流失率會更大。

+0

如果瑪麗2010年離開,但卡爾加入同一年,換手率是0.0還是0.5? – pshep123

+0

@ pshep123:它始終基於過去一年中停留在當年的人數。所以約翰會在2009年停留,而換手率是0.5。他可能是一個憤怒的老闆,因爲它是從一開始就存活下來的人:-) – neves

+0

2008年不是它應該是.333嗎? 2007年有3人,剩下2人。 – jdehesa

回答

3

該計劃

  • 我要設定'year''teachers'指數,所以我assign一個虛擬變量提前。
  • 我想要有'year'作爲我的索引,所以我unstack'teachers'放在列中。我使用fill_value=0選項填寫教師不在某一年的零年。
  • 使用diff並檢查是否等於-1標識週轉事件。 sum(1)總結所有周轉事件。
  • d1.sum(1).shift()統計上一年度的所有教師。
  • 分得到營業額。

d1 = pd.Series(1, [df.year, df.teachers]).unstack(fill_value=0) 
d1.diff().eq(-1).sum(1).div(d1.sum(1).shift(), 0).dropna() 

year 
2008 0.333333 
2009 0.750000 
dtype: float64 

正如評論所指出的@jrjc,我的第一行是一個crosstab。考慮到這一點,我們可以減少代碼:

d1 = pd.crosstab(df.year, df.teachers) 
d1.diff().eq(-1).sum(1).div(d1.sum(1).shift(), 0).dropna() 

一個使用pipe

pd.crosstab(df.year, df.teachers).pipe(
    lambda c: c.diff().eq(-1).sum(1).div(c.sum(1).shift(),0).dropna() 
) 
+0

你的'd1'只是一個交叉表:'d1 = pd.crosstab(df.year,df.teachers)'。下一行雖然不錯! – jrjc

+0

@jrjc當然,你是對的......奇怪的是,在某些場景下,我的方式更快。然而,速度並不是我的焦點,「crosstab」更加優雅。 – piRSquared

1

這裏有一個可能性:

from io import StringIO 

import numpy as np 
import pandas as pd 

data = pd.read_table(StringIO(
""" teachers year 
0  John 2007 
1  Paul 2007 
2  Mary 2007 
3  John 2008 
4  Paul 2008 
5  Abel 2008 
6  Watt 2008 
7  John 2009 
8  Mary 2009""" 
), delim_whitespace=True, index_col=0) 

data['presence'] = 1 
teacher_presence = data.groupby(['teachers', 'year']).count().unstack(1).fillna(0) 
teacher_presence.columns = teacher_presence.columns.droplevel(0) 

teacher_remain = teacher_presence.iloc[:, 1:] * teacher_presence.iloc[:, :-1].values 
turnover = 1 - teacher_remain.sum()/teacher_presence.iloc[:, :-1].sum().values 
turnover.name = 'turnover' 

print(turnover) 

結果:

year 
2008 0.333333 
2009 0.750000 
Name: turnover, dtype: float64 
0

您也可以分組後教師轉換成set,再行執行這組操作。

In [72]: t = df.groupby('year')['teachers'].apply(lambda x: set(x.values.tolist())) 

In [73]: t 
Out[73]: 
year 
2007   {John, Paul, Mary} 
2008 {John, Abel, Paul, Watt} 
2009    {John, Mary} 
Name: teachers, dtype: object 

In [76]: t.combine(t.shift(), lambda a, b: len(b-a)/len(b) if isinstance(b, set) else np.nan).dropna() 
Out[76]: 
year 
2008 0.333333 
2009  0.75 
Name: teachers, dtype: object