2016-08-23 28 views
5

Ben de düzeltmek istiyorum bazı yanlış bilgiler içeren bir dataframe vardır:Python Pandalar GroupBy Endeksi'nde dayanarak

import pandas as pd 
tuples_index = [(1,1990), (2,1999), (2,2002), (3,1992), (3,1994), (3,1996)] 
index = pd.MultiIndex.from_tuples(tuples_index, names=['id', 'FirstYear']) 
df = pd.DataFrame([2007, 2006, 2006, 2000, 2000, 2000], index=index, columns=['LastYear']) 


df 
Out[4]: 
       LastYear 
id FirstYear   
1 1990   2007 
2 1999   2006 
    2002   2006 
3 1992   2000 
    1994   2000 
    1996   2000 

kimliği işletme anlamına gelir ve bu DataFrame bir küçük örnek dilim Bir işin nasıl hareket ettiğini gösteren daha büyük bir tane. Her kayıt benzersiz bir konum ve ben ilk ve geçen yıl orada yakalamak istiyorum. Geçerli 'LastYear', sadece bir rekoru olan ve birden fazla rekor için işletmelerin en son rekoru için doğru olan işletmeler için doğrudur. Ne df sonunda gibi görünmelidir şudur:

   LastYear 
id FirstYear   
1 1990   2007 
2 1999   2002 
    2002   2006 
3 1992   1994 
    1994   1996 
    1996   2000 

Ve bunu almak için ne yaptığını süper aksak vardı:

multirecord = df.groupby(level=0).filter(lambda x: len(x) > 1) 
multirecord_grouped = multirecord.groupby(level=0) 

ls = [] 
for _, group in multirecord_grouped: 
    levels = group.index.get_level_values(level=1).tolist() + [group['LastYear'].iloc[-1]] 
    ls += levels[1:] 

multirecord['LastYear'] = pd.Series(ls, index=multirecord.index.copy()) 
final_joined = pd.concat([df.groupby(level=0).filter(lambda x: len(x) == 1),multirecord]).sort_index() 

daha iyi bir yolu var mı?

cevap

5
shift_year = lambda df: df.index.get_level_values('FirstYear').to_series().shift(-1) 
df.groupby(level=0).apply(shift_year) \ 
    .combine_first(df.LastYear).astype(int) \ 
    .rename('LastYear').to_frame() 

enter image description here

+0

başka kim, ancak, sadece bir satır ile yapılır tüm bu alabilir? – Kartik

+0

, bu işlemden bahsetmediğiniz için üzgünüm, fakat bunun çalıştırılmakta olduğu veri şeması ~ 54 milyon satırdır. Bu kod çok zarif ama koşmak için saatler alacak. Hızlandırabilecek bir şey düşünebilir misin? – jesseWUT