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

Posted

技术标签:

【中文标题】Python pandas:替换 groupby 对象中的选择值【英文标题】:Python pandas: replace select values in groupby object 【发布时间】:2014-10-30 22:29:18 【问题描述】:

我有一个大型数据框,其中包含四列中的个人级别数据:人员 ID 号、她的年份、她的年龄和她的移动状态。我在个人 ID 号上使用groupby,存储在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

对于每个组,我想在 movedage 列中填写等于零的值 具有备用值,但仅当这些观察值“夹在”其他观察值之间时,agemoved 列中至少有一个非零值。

例如,在上面的组中,我想填写行798914: 798918,而不是798908:798911.. 对于agemoved 值都等于0 的观察值,我写了一个相应地替换零的函数。但我想在 798914: 798918 这样的“三明治”案例上调用此函数,但不知道如何访问这些行。

到目前为止,我已经尝试过类似的方法:

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

但这会填充非夹层观察,如上述组中的前四行。我应该如何应用一个函数来填充每个组中等于 0 的 agemoved 值,但仅适用于夹在agemovedmoved 中的非零值观察之间的观察。还是两者都有?

【问题讨论】:

你能只选择所有零行的组子集的索引吗?然后,使用逻辑 lambda 找到第一组 0 中断的位置(现在的索引 = 1+之前的索引吗?)。然后,在第一次中断 0 之后但在下一组零之前对行子集使用 ur 函数。那有意义吗?可能有更聪明的方法。 【参考方案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

【讨论】:

以上是关于Python pandas:替换 groupby 对象中的选择值的主要内容,如果未能解决你的问题,请参考以下文章

pandas如何使用groupby [duplicate]将NaN值替换为平均值

numpy 或 pandas groupby 方式替换 2 个 for 循环

Python、Pandas:GroupBy 属性文档

python pandas groupby分组后的数据怎么用

python [groupby]示例groupby #pandas #secret

[Python Cookbook] Pandas Groupby