【问题标题】:see trend change by group (python pandas dataframe)按组查看趋势变化(python pandas 数据框)
【发布时间】:2017-06-04 10:25:20
【问题描述】:

我正在尝试根据下面的现有数据框创建一个新的数据框。我的目标是计算点击次数的平均变化并相应地对广告系列进行分类。

现有数据框df:

campaign    |     date     |    clicks 
   A           2015-10-11       255
   A           2015-10-12       367
   A           2015-10-13       489
   B           2015-10-11       500
   B           2015-10-15       122
   C           2015-10-11       33

目标数据框 df_categorized:

campaign | avg_change |   category
   A        0.3858       increasing
   B        -0.756       decreasing
   C           0         no change

我尝试了此代码,但收到错误消息 TypeError: 'long' object does not support item assignment

 #standard packages
 import pandas as pd
 import numpy as np

 #upload data into df
 df = pd.read_csv('C:\Users\xxx\Documents\\ad_table.csv')

 df.head()
 campaign    |     date     |    clicks 
   A           2015-10-11       255
   A           2015-10-12       367
   A           2015-10-13       489
   B           2015-10-11       500
   B           2015-10-15       122
   C           2015-10-11       33

 #create empty dataframe
 columns = ['group','avg_change', 'category']     
 df_categorized = pd.DataFrame(columns=columns)

 df_categorized['avg change'] = df.clicks.apply(lambda df:       df.pct_change().abs().mean())

 #create column
 df_categorized['category'] = 0
 # going up
 df_categorized['category'][df_categorized['avg change'] > 0] = "increasing"
 # going down
 df_categorized['category'][df_categorized['avg change'] < 0] = "decreasing"
 #no change
 df_categorized['category'][df_categorized['avg change'] = 0] = "no change"

【问题讨论】:

  • 即使你称它为df,lambda 函数中的参数也是系列的一个元素,即一个标量。当您将函数应用于系列时(此处为 df.clicks),该函数将按元素应用。
  • 您可以通过简单的最后减去第一个来跟踪平均变化
  • 同样采用abs的变化不会告诉你谁在减少或增加!

标签: python loops pandas categories


【解决方案1】:

您可以 groupby 在“广告系列”上,然后 apply lambda 计算 pct_change 并返回 mean。然后您可以在此reset_index 并使用np.where 添加其他类别列:

In [239]:
gp = df.groupby('campaign')['clicks'].apply(lambda x: x.pct_change().mean()).reset_index(name='avg_change').fillna(0)
gp['category'] = np.where(gp['avg_change'] < 0, 'decreasing', np.where(gp['avg_change'] > 0, 'increasing', 'no change'))
gp

Out[239]:
  campaign  avg_change    category
0        A     0.38582  increasing
1        B    -0.75600  decreasing
2        C     0.00000   no change

这个:

df_categorized['avg change'] = df.clicks.apply(lambda df: df.pct_change().abs().mean())

不起作用,您在列上调用 apply,因此 lambda 将是每个行元素,在这种情况下是 int,因此您会收到错误:

AttributeError: 'int' object has no attribute 'pct_change'

即使没有这个,它也不会给你每个广告系列的 pct_change。

也不要像这样在你的 df 上链接调用:

df_categorized['category'][df_categorized['avg change'] > 0] = "increasing"

应该是:

df_categorized.loc[df_categorized['avg change'] > 0, 'category'] = "increasing"

docs

【讨论】:

  • 谢谢!这非常有帮助,尤其是这些建议,我将继续使用它们——当我在整个数据集上运行上面的代码时,我只得到积极的变化或“inf”——“inf”是什么意思?
  • 表示无穷大,表示你可能在某处被零除
  • 我明白了;所以我需要用 dropna 或 df = df[df.clicks != 0] 删除这些值?
  • 这听起来很合理,在您的场景中包含它们可能毫无意义
  • 另外,如果我的回答解决了你的问题,那么你可以接受它,我的回答左上角会有一个空勾
猜你喜欢
  • 2016-08-10
  • 1970-01-01
  • 2021-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多