2014-09-05 65 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