2017-02-11 5 views
1

を展開します。パンダ:私は採用の人々と年のデータフレームを持つデータフレームの行単位、RのSurvSplit(に類似)

person_id years     
1   1.00 
2   2.34 
3   6.85 

を私は行方向事前定義された「チャンクに基づいてデータフレームを展開したいです"従業員の在籍期間中。私は1年マークでチャンク人の任期にしたい場合たとえば、上記のデータフレームになるでしょう:

person_id tstart tend     
1   0.00 1.00 
2   0.00 1.00 
2   1.00 2.34 
3   0.00 1.00 
3   1.00 6.85 

私は1年と2年のマークでチャンクに望んでいた場合は、元のデータフレームは次のようになります。

だから、
person_id tstart tend     
1   0.00 1.00 
2   0.00 1.00 
2   1.00 2.00 
2   2.00 2.34 
3   0.00 1.00 
3   1.00 2.00 
3   2.00 6.85 

、理想的には、私が(年1および2のチャンクに例えば[1,2])行方向の拡大を指示するチャンクのlistまたはtupleを提供したい

このデータフレームの操作はRののようになります- 127ページを参照here

どうすればいいですか?私はStackoverflowに関するいくつかの記事を見つけましたが、異なるデータフレーム拡張の目標について議論します。

答えて

1

次の定義された方法を検討してください。ウォークスルー、それのビットは以下C.

で書かれているsurvsplit実際のソースコードとは異なり、何のループを使用しませんが、基本的にクロスがチャンク引数の最大の反復在職年の参加で実行され、ポイントにマージ人物。次に、tstartおよびtendカラムを持つ元のデータフレーム値は、mergeの結果に連結されます。 キーがここされ、元のデータフレームに割り当てる必要があります:

from io import StringIO 
import pandas as pd 
import numpy as np 

persons = pd.read_table(StringIO("""person_id years     
1   1.00 
2   2.34 
3   6.85"""), sep="\s+").assign(key = 1) 

def expand_tenure(chunk): 
    newpersons = persons.assign(tstart = chunk, tend = persons['years']) 
    newpersons.loc[newpersons['tend'] < chunk, 'tstart'] = np.floor(persons['years']) 

    df = pd.DataFrame({'tstart': list(range(0, chunk)), 
         'tend': list(range(1, chunk+1)), 
         'key': 1}) 

    mdf = pd.merge(persons, df, on='key')  
    mdf = mdf[mdf['tend'] <= mdf['years']][['person_id', 'tstart', 'tend']] 

    cdf = pd.concat([newpersons[['person_id', 'tstart', 'tend']], mdf])\ 
        .sort_values(['person_id', 'tstart'])\ 
        .drop_duplicates(['person_id', 'tend']).reset_index(drop=True) 

    return cdf 

出力(3回の実行)

print(expand_tenure(1)) 
# person_id tstart tend 
# 0   1  0.0 1.00 
# 1   2  0.0 1.00 
# 2   2  1.0 2.34 
# 3   3  0.0 1.00 
# 4   3  1.0 6.85 

print(expand_tenure(4)) 
# person_id tstart tend 
# 0   1  0.0 1.00 
# 1   2  0.0 1.00 
# 2   2  1.0 2.00 
# 3   2  2.0 2.34 
# 4   3  0.0 1.00 
# 5   3  1.0 2.00 
# 6   3  2.0 3.00 
# 7   3  3.0 4.00 
# 8   3  4.0 6.85 

print(expand_tenure(12)) 
#  person_id tstart tend 
# 0   1  0.0 1.00 
# 1   2  0.0 1.00 
# 2   2  1.0 2.00 
# 3   2  2.0 2.34 
# 4   3  0.0 1.00 
# 5   3  1.0 2.00 
# 6   3  2.0 3.00 
# 7   3  3.0 4.00 
# 8   3  4.0 5.00 
# 9   3  5.0 6.00 
# 10   3  6.0 6.85 
+0

素晴らしい、ありがとうございました! – NickBraunagel

関連する問題