根据其他列的分组设置列的值

3

我将使用pandas的loc方法通过条件筛选DataFrame,并给另一列赋值。

初始化DataFrame

import random
random.seed(100)

nums = 100
df = pd.DataFrame({'value':[random.randint(-7, 10) for x in range(nums)],
                      'id': [random.randint(500, 520) for x in range(nums)], 
                     'prod': [random.choice(['carrots', 'apples', 'pears', 'corn', 'baby corn', 'peppers', 'jalapenos', 'chicken', 'beef', 'raddishes']) for x in range(nums)],
                     'region':[random.choice(['east', 'west', 'central', 'south']) for x in range(nums)],
                     'country':[random.choice(['us', 'ca', 'mx']) for x in range(nums)],
                     'tag': np.nan})

我正在尝试做类似于“按usca过滤数据集,但仅限于eastwest地区,并且在分组的prodid中值的总和为负数。”

以下操作将数据框按刚刚分组的内容进行索引,但我想通过索引来隔离这些内容。

df.groupby(['id', 'prod'])['value'].sum().loc[lambda x: x <0].head(10)

id   prod     
500  apples      -6
     carrots     -6
     corn        -6
501  apples      -3
     chicken     -2
502  beef        -3
     pears       -2
503  chicken     -3
504  jalapenos   -4
505  chicken     -4

我正在尝试做类似于以下的事情:
df.loc[(df.country.isin(['us', 'ca'])) & (df.region.isin(['east', 'west'])) & (df.groupby(['id', 'prod'])['value'].sum().loc[lambda x: x <0]), 'tag'] = True

如何将groupby后的数据框结果用作pandas loc中的过滤器?


很遗憾,我只能给你一个赞,因为你的设置非常好。有一个数据集确实很有帮助。 - Anton vBR
1个回答

2
如果你使用.transform('sum')而不是.sum(),则会返回每行的分组结果。通过将该值与< 0进行比较,您可以得到布尔蒙版。
然后,我们可以在单独的行上创建不同的掩码,并使用&将它们连接起来。
m1 = df.country.isin({'us', 'ca'})
m2 = df.region.isin({'east', 'west'})
m3 = df.groupby(['id', 'prod'])['value'].transform('sum') < 0

df.loc[m1&m2&m3, 'tag'] = True

这对你有帮助吗?


太好了,谢谢!我不知道 transform 会返回索引。 - Matt W.
@MattW。如果你指的是值,那么你是对的。但是当我们与< 0进行比较时,我们会得到一个布尔掩码,其中包含TrueFalse,我们可以将其与其他掩码组合使用。很高兴我能帮到你! - Anton vBR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接