Python pandas:在groupby对象中替换选定值
我有一个很大的数据表,里面有四列个人信息:一个人 ID 号码、年份、年龄和搬家状态。我使用 groupby
方法根据个人 ID 号码(存储在 unique_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
列中等于零的值填上其他的值,但只有在这些零值的观察数据被至少一个非零值的观察数据“夹住”的情况下,也就是说,前后都有非零的值。
比如,在上面的组中,我想填充 798914: 798918
这几行,但不想填充 798908:798911
。对于那些 age
和 moved
值都是 0 的观察数据,我已经写了一个函数来相应地替换这些零值。但我想在“夹住”的情况下,比如 798914: 798918
,调用这个函数,但我不知道怎么找到这些行。
到目前为止,我尝试了类似这样的代码:
group.loc[(group["age"] == 0) & (group["moved"] == 0), ['age', 'moved']] = someFunction(group)
但是这填充了那些没有被夹住的观察数据,比如上面组的前四行。我该如何处理,才能在每个组中只对那些被夹住的观察数据应用这个函数,填充 age
和 moved
值为 0 的情况,而这些观察数据的前后都有非零值呢?
1 个回答
1
假设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