2014-09-05 62 views
1

我有一個大型的數據框,包含四列中的個人級數據:人員ID號,她的年份,她的年齡和她的移動狀態。我在人身份號碼上使用groupby,存儲在列unique_pid2Python熊貓:替換groupby對象中的選擇值

import pandas as pd 

gr_data = pd.read_csv("M:/test.csv").groupby('unique_pid2') 

group = gr_data.get_group('5904_181') 

print group 

每組看起來像這樣:

 unique_pid2 year age moved 
798908 5904_181 1983 0  0 
798909 5904_181 1984 0  0 
798910 5904_181 1985 0  0 
798911 5904_181 1986 0  0 
798912 5904_181 1987 2  5 
798913 5904_181 1988 0  5 
798914 5904_181 1989 0  0 
798915 5904_181 1990 0  0 
798916 5904_181 1991 0  0 
798917 5904_181 1992 0  0 
798918 5904_181 1993 0  0 
798928 5904_181 2009 24  5 
798929 5904_181 2011 26  1 

對於每個組,我想填寫中等於在兩個movedage列 具有替代值零值,但僅當這些觀察結果夾在agemoved列中至少有一個非零值的其他觀察值之間。

例如,在上述組中,我想填寫線條798914: 798918,但不是798908:798911 ..對於具有兩個agemoved值等於0時,觀察,我已經寫,它取代了在零相應的功能。但是我想在798914: 798918這樣的「三明治」情況下調用這個函數,並且不知道如何訪問這些行。

到目前爲止,我已經試過類似:

group.loc[(group["age"] == 0) & (group["moved"] == 0), ['age', 'moved']] = someFunction(group) 

但這填補了非夾着觀察,如上面的組中的前四行。我應該如何應用函數來填充每個組中等於0的值agemoved,但僅限於夾在age,moved或兩者中的非零值觀察值之間的觀測值?

+1

你能不能選擇具有所有零行集團的子集的索引?然後,使用邏輯lambda找到第一組0的位置(現在的索引= 1 +索引?)。然後,在0s中的第一次中斷之後但在下一組零之前,對行的子集使用ur函數。那有意義嗎?可能有更聰明的方法。 – robertevansanders 2014-09-05 22:41:48

回答

1

假設值agemoved都是非負,則使用cumsum可以選擇所需要的行數:

mask = ((grp['age'].cumsum()>0) & (grp['moved'].cumsum()>0) 
     & (grp['age'] == 0) & (grp['moved'] == 0)) 

,因爲當累計和大於0,一定有一個前面的正的值。

例如,

import pandas as pd 

df = pd.read_csv("M:/test.csv") 
gr_data = df.groupby('unique_pid2') 
def foo(grp): 
    mask = ((grp['age'].cumsum()>0) & (grp['moved'].cumsum()>0) 
      & (grp['age'] == 0) & (grp['moved'] == 0)) 
    grp.loc[mask, ['age', 'moved']] = 'foo' 
    return grp 
df = gr_data.apply(foo) 
print(df) 

產生

unique_pid2 year age moved 
0  5904_181 1983 0  0 
1  5904_181 1984 0  0 
2  5904_181 1985 0  0 
3  5904_181 1986 0  0 
4  5904_181 1987 2  5 
5  5904_181 1988 0  5 
6  5904_181 1989 foo foo 
7  5904_181 1990 foo foo 
8  5904_181 1991 foo foo 
9  5904_181 1992 foo foo 
10 5904_181 1993 foo foo 
11 5904_181 2009 24  5 
12 5904_181 2011 26  1