【问题标题】:ranking transactions trend for each customer per year对每个客户每年的交易趋势进行排名
【发布时间】:2019-05-05 02:02:31
【问题描述】:

在 jupyter 上工作,我的数据框有每个客户每年的交易数量和字段,表明“趋势 - 交易量比去年多,交易量比去年少,第一年为空。

我想创建一个分子,每个客户每“上升”一次,就会增加 1,每“下降”一次,就会“减少”1。

我知道我需要首先对 df 进行排序,然后构建一个根据客户数量运行的循环和一个每年都会运行的内部循环,但我需要帮助。

DF 样本:

df = pd.DataFrame({
    'group number': [1,1,1,1,3,3,3],
    'year': ['2012','2013','2014','2015','2011','2012','2013'],
    'trend': [NaN,'down','up','up',NaN,'down','up']
}) 

这是我到目前为止所做的:

df =pd.read_excel('totals_new.xlsx',sheet_name='Sheet1').sort_values(['group number', 'year'])

noofgroups = len(df['group number'].unique())
yearspergroup = df.groupby('group number')['year'].nunique()

vtrend =0

for i in noofgroups:
    for j in yearspergroup:
        if df["trend"] == "up":
            vtrend = vtrend+1
        if df["trend"] == "down":
            vtrend = vtrend-1

【问题讨论】:

  • 欢迎来到 StackOverflow!如果您可以提供您已经尝试过的代码 sn-p,则更适合该社区,因此我们可以提出改进建议。

标签: python pandas loops for-loop


【解决方案1】:

这个案子现在可能已经结案了,但是,这是一个可能的解决方案,因为它之前没有得出结论。

import pandas as pd

"""
In this case, the original dataframe is already properly sorted by group number and year.
If it isn't, the 2 columns should be sorted first
"""
df = pd.DataFrame({
    'group number': [1,1,1,1,3,3,3],
    'year': ['2012','2013','2014','2015','2011','2012','2013'],
    'trend': [np.nan,'down','up','up', np.nan,'down','up']
}) 

df['trend_val'] = df.loc[df['trend'].isna() == False, 'trend'].map(lambda x: -1 if x == 'down' else 1)
df.join(df.groupby('group number')['trend_val'].cumsum(), rsuffix='_cumulative')

>>>df
   group number  year trend  trend_val  trend_val_cumulative
0             1  2012   NaN        NaN                   NaN
1             1  2013  down       -1.0                  -1.0
2             1  2014    up        1.0                   0.0
3             1  2015    up        1.0                   1.0
4             3  2011   NaN        NaN                   NaN
5             3  2012  down       -1.0                  -1.0
6             3  2013    up        1.0                   0.0

【讨论】:

    【解决方案2】:

    IIUC,您可以使用嵌套的np.where() 转换您的trend 列,然后执行groupby()agg()。拿这个示例数据框:

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame({
        'group number': [1,1,1,1,1,1,1,2,2,2,2,2,2,1,1,1,2,2,1,2,1,2],
        'year': ['2017','2016','2018','2017','2016','2018','2017','2016','2018','2017','2016','2018',
            '2017','2016','2018','2017','2016','2018','2017','2016','2018','2017'],
        'trend': ['up','down','up',np.nan,'up','down',np.nan,'up','up','up','down',
            'up',np.nan,'up','up','up','down','up','up','up',np.nan,'down']
        })
    

    产量:

        group number  year trend
    0              1  2017    up
    1              1  2016  down
    2              1  2018    up
    3              1  2017   NaN
    4              1  2016    up
    5              1  2018  down
    6              1  2017   NaN
    7              2  2016    up
    8              2  2018    up
    9              2  2017    up
    10             2  2016  down
    11             2  2018    up
    12             2  2017   NaN
    13             1  2016    up
    14             1  2018    up
    15             1  2017    up
    16             2  2016  down
    17             2  2018    up
    18             1  2017    up
    19             2  2016    up
    20             1  2018   NaN
    21             2  2017  down
    

    然后:

    df['trend'] = np.where(df['trend']=='up', 1, np.where(df['trend']=='down', -1, 0))
    
    df.groupby(['group number','year']).agg({'trend': 'sum'})
    

    返回:

                       trend
    group number year       
    1            2016      1
                 2017      3
                 2018      1
    2            2016      0
                 2017      0
                 2018      3
    

    【讨论】:

    • 谢谢,但是对于每个组的第一年,趋势是“null”,所以 where 子句需要将 null 设为零,你能解决它吗?
    • 出于这个原因,您需要发布数据框的样本。
    • 请勿以图片形式发布,请将其作为格式化文本包含在您的原始帖子中。请参阅发布指南
    • 谢谢,我试过了,但它会自动发布为图片:(
    • 添加到帖子中希望没问题
    猜你喜欢
    • 2022-07-07
    • 2022-01-01
    • 1970-01-01
    • 2021-05-11
    • 1970-01-01
    • 1970-01-01
    • 2020-05-24
    • 2020-08-30
    • 1970-01-01
    相关资源
    最近更新 更多