Python:替换groupby对象中的选择值

Python:替换groupby对象中的选择值,python,csv,pandas,indexing,Python,Csv,Pandas,Indexing,我有一个很大的数据框,其中包含四列个人级别的数据:个人id号、她的年份、年龄和移动状态。我对个人id号使用groupby,该编号存储在unique\u pid2列中 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

我有一个很大的数据框,其中包含四列个人级别的数据:个人id号、她的年份、年龄和移动状态。我对个人id号使用
groupby
,该编号存储在
unique\u pid2列中

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
对于每个组,我希望在
moved
age
列中填写等于零的值 具有替代值,但仅当这些观察值“夹在”其他观察值之间时,在
age
moved
列中至少有一个非零值

例如,在上面的组中,我想填写行
798914:798918
,但不是
798908:798911
。。对于
age
moved
值都等于0的观测值,我编写了一个函数,相应地替换其中的零。但是我想在“三明治”情况下调用这个函数,比如
798914:798918
,但我不知道如何访问这些行

到目前为止,我已经尝试过以下方法:

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

但这会填充非三明治式的观察结果,就像上面组中的前四行一样。我应该如何应用函数来填充各组中等于0的
age
moved
值,但仅适用于夹在
age
moved
中非零值的观察值,或者两者都有?

假设
age
moved
中的值为非负值,您可以使用
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

您可以只选择包含所有零行的组的子集的索引吗?然后,使用逻辑lambda查找第一组0在何处断开(现在的索引是否=1+以前的索引?)。然后,在0s中第一次中断之后但在下一组零之前的行子集上使用ur函数。这有意义吗?也许还有更聪明的办法。