Python:替换groupby对象中的选择值
我有一个很大的数据框,其中包含四列个人级别的数据:个人id号、她的年份、年龄和移动状态。我对个人id号使用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
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函数。这有意义吗?也许还有更聪明的办法。