在 Pandas 中有条件地设置分组的值(Python)。

3

我有一个包含以下列的数据框:

duration, cost, channel 
  2       180      TV1
  1       200      TV2
  2       300      TV3
  1       nan      TV1
  2       nan      TV2
  2       nan      TV3
  2       nan      TV1
  1       40       TV2
  1       nan      TV3

一些成本数值为nans,为了填补它们,我需要做以下操作:

  • 按频道分组
  • 在一个频道内,将可用成本相加并除以*出现次数(平均值)
  • 重新分配该频道内所有行的值:
    • 如果持续时间=1,则成本=平均值*1.5
    • 如果持续时间=2,则成本=平均值

例如: TV2频道,我们有3个条目,其中一个条目成本为空。因此,我需要执行以下操作:

average = 200+40/3 = 80
if duration = 1, cost = 80 * 1.5 = 120

duration, cost, channel 
  2       180      TV1
  1       120      TV2
  2       300      TV3
  1       nan      TV1
  2       80       TV2
  2       nan      TV3
  2       nan      TV1
  1       120      TV2
  1       nan      TV3

我知道我应该使用 df.groupby('channel') 然后对每个组应用函数。 问题在于,如果有一个成本为空,我不仅需要修改空值,而且需要修改组内的所有成本值。
任何提示都将不胜感激。
谢谢!
2个回答

9
如果我理解您的问题正确,您想要类似以下内容的东西:
def myfunc(group):

    # only modify cost if there are nan's
    if len(group) != group.cost.count():

        # set all cost values to the mean
        group['cost'] = group.cost.sum() / len(group)

        # multiply by 1.5 if the duration equals 1
        group['cost'][group.duration == 1] = group['cost'] * 1.5

    return group


df.groupby('channel').apply(myfunc)

   duration  cost channel
0         2    60     TV1
1         1   120     TV2
2         2   100     TV3
3         1    90     TV1
4         2    80     TV2
5         2   100     TV3
6         2    60     TV1
7         1   120     TV2
8         1   150     TV3

谢谢!但是df中的cost列没有被分配新值。当我执行df.cost = df.groupby('channel').apply(myfunc)时,出现了错误。 - ybb
1
在这种情况下,apply函数已经返回了与原始df完全相同的数据框,只是成本值不同。因此,您可以执行以下操作:df = df.groupby('channel').apply(myfunc)。但是,如果您坚持只修改成本列,则也可以使用以下代码:df['cost'] = df.groupby('channel').apply(myfunc)['cost']。但我不建议使用后者,因为索引的更改可能会导致不对齐,尽管在这种情况下它可以工作。 - Rutger Kassies

2
在新版本的 Pandas 中,代码应该更改为:
def myfunc(group):
    # only modify cost if there are nan's
    if len(group) != group.cost.count():

        # set all cost values to the mean
        group['cost'] = group.cost.sum() / len(group)

        # multiply by 1.5 if the duration equals 1
        _ = group.set_value(group[group.duration == 1].index, 'cost', group['cost'] * 1.5)

    return group

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