【问题标题】:How to get "scalar" value from pandas Dataframe based on columns values conditions?如何根据列值条件从熊猫数据框中获取“标量”值?
【发布时间】:2020-11-20 09:32:07
【问题描述】:

这是我的 pandas df 的形式:

id year CW value
c1 2020 45 5543.3
c2 2020 45 4434 
c3 2020 45 3343.4
c4 2020 45 2399.62
c5 2020 45 1233.34
c1 2020 44 5432
c5 2020 44 4423
c4 2020 44 3342.34
c3 2020 44 2322.3
c2 2020 44 1677.5
...
...
...
c2 2019 2 5222.3
c1 2019 2 4444 
c4 2019 2 3333
c3 2019 2 2222.62
c5 2019 2 1111.34
c5 2019 1 5959
c3 2019 1 4949
c1 2019 1 3939.34
c4 2019 1 2929.3
c2 2019 1 1919.5

数据框按“年”、“CW”、“值”降序排列。

我想比较 c1、c2、c3、c4 和 c5 的最新一周表现,以每个 CW(日历周)的价值与实际年份的前一周和去年的百分比相比。

如何获取今年前一周和去年c1、c2、c3等的值?

例如对于 c1,我尝试了以下代码,但不知何故我得到了错误。我使用 iloc[0] 因为 df 是降序排序的。并尝试将“cw”从字符串转换为 int,这样我就可以减去 1 以得到前一个“cw”(例如,从 45 到 44)。

first_wow = (df[(df['c1'] == df.iloc[0]['c1']) & (
                int(df['cw']) == int(df.iloc[0]['cw']))].cnt.values[0] - df[
                        (df['c1'] == df.iloc[0]['c1']) & (
                                    int(df['cw']) == int(df.iloc[0]['cw']) - 1)].cnt.values[0]) / df[
                       (df['c1'] == df.iloc[0]['c1']) & (
                                   int(df['cw']) == int(df.iloc[0]['cw']) - 1)].cnt.values[0]

【问题讨论】:

  • 那么基本上如何根据上述条件获取值...如何提取前一周/一年(同一周)的 c1 值?

标签: python pandas numpy dataframe data-analysis


【解决方案1】:

这是一种利用 pandas groupby 方法的方法:

def prev_year(df):
    df = df.sort_values(['year'],ascending=[False])
    df['val_prev_yr'] = df['value'].shift(-1)
    df['prev_yr_diff'] = df['value'] - df['val_prev_yr']
    df['prev_yr_perc_diff'] = 100.0*df['prev_yr_diff']/df['val_prev_yr']
    return df

def prev_week(df):
    df = df.sort_values(['CW'],ascending=[False])
    df['val_prev_week'] = df['value'].shift(-1)
    df['prev_week_diff'] = df['value'] - df['val_prev_week']
    df['prev_week_perc_diff'] = 100.0*df['prev_week_diff']/df['val_prev_week']
    return df

def calcs(df):
    
    df2 = df.groupby('year').apply(prev_week).reset_index(drop=True)
    df2 = df.merge(df2[['val_prev_week','prev_week_diff','prev_week_perc_diff','year','CW']],how='left',on=['year','CW'])
    
    df3 = df2.groupby('CW').apply(prev_year).reset_index(drop=True)
    df4 = df2.merge(df3[['val_prev_yr','prev_yr_diff','prev_yr_perc_diff','year','CW']],how='left',on=['year','CW'])
    
    return df4
    
    
df.groupby('id').apply(calcs).sort_values(['year','CW'],ascending=[False,False]).reset_index(drop=True)

【讨论】:

  • 让我知道这是否是您所追求的,然后我可以添加 cmets 来描述正在发生的事情!
  • 是的,这确实是我需要的!!!非常感谢!!!真的很有帮助!只是想问你,如果我有另一个分组级别(维度)是“国家”,我该如何管理它? (我有 3 个国家,国家 1、国家 2 和国家 3,我想要所有 3 个国家的上述值......
  • 很高兴这有帮助 :) 因此,要按国家/地区对以上内容进行分组,您可以编写一个新的分组函数,该函数返回上面代码的最后一行:def country_group_calcs(df): return df.groupby('id').apply(calcs)....,然后只需使用 @ 调用此函数987654326@(假设您的国家列称为“国家”)。
  • 然后如果您想整理最终输出的行索引(这将是一个 MultiIndex),您可以使用 .reset_index(drop=True) 重置和删除索引
猜你喜欢
  • 1970-01-01
  • 2023-02-21
  • 2017-06-26
  • 2021-06-05
  • 2022-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多