【问题标题】:Data manipulation in pandas on monthly, quarterly and annual level on multiple columnsPandas 在多列的月度、季度和年度级别上进行数据操作
【发布时间】:2022-02-20 22:24:42
【问题描述】:

我需要创建一个函数,它将输入作为字典并更新数据框中的列值。我的数据如下所示

Date Col_1 Col_2 Col_3 Col_4 Col_5
01/01/2021 10 20 10 20 10
02/01/2021 10 20 10 20 10
03/01/2021 10 20 10 20 10
04/01/2021 10 20 10 20 10
05/01/2021 10 20 10 20 10
06/01/2021 10 20 10 20 10
07/01/2021 10 20 10 20 10
08/01/2021 10 20 10 20 10
09/01/2021 10 20 10 20 10
10/01/2021 10 20 10 20 10
11/01/2021 10 20 10 20 10
12/01/2021 10 20 10 20 10

现在,如果通过“Col_1”和“Col_2”的每月级别更新百分比,比如说

{Date: ['01/01/2021','02/01/2021','03/01/2021','04/01/2021','05/01/2021','06/01/2021',
        '07/01/2021','08/01/2021','09/01/2021','10/01/2021','11/01/2021','12/01/2021',],
 'Col_1': [20,20,20,20,30,30,40,40,20,20,20,20],
 'Col_2': [0,0,0,0,0,0,0,0,0,0,10,10]}

执行此操作后,我想要的每月变化如下所示

Date Col_1 Col_2 Col_3 Col_4 Col_5
01/01/2021 12 20 10 20 10
02/01/2021 12 20 10 20 10
03/01/2021 12 20 10 20 10
04/01/2021 12 20 10 20 10
05/01/2021 13 20 10 20 10
06/01/2021 13 20 10 20 10
07/01/2021 14 20 10 20 10
08/01/2021 14 20 10 20 10
09/01/2021 12 20 10 20 10
10/01/2021 12 20 10 20 10
11/01/2021 12 24 10 20 10
12/01/2021 12 24 10 20 10

同样,我也想更新我的季度和年度数据。我能够进行年度更新,这是我的代码。请根据输入帮助我进行每月和每季度的更新。

谢谢!!

dic = {'col_1':10,'col_2':-5)
year = 2021
def update_df(dic,df,year):
    df = df[df['date'].dt.year == year]
    df = (df+df.select_dtypes(include = 'number').mul(pd.Series(dic)/100)).combine_first(df)[df.columns]
    return df

我正在尝试这样

def update_df(dic,df,year,choice):     
    if choice == annual:         
        df = df[df['date'].dt.year == year]         
        df = (df+df.select_dtypes(include =                 
'number').mul(pd.Series(dic)/100)).combine_first(df)[df.columns]        
    elif choice == quarterly :          
        df["quarter"] = df.date.dt.quarter           
        df = (df+df.select_dtypes(include =                   
        'number').mul(pd.Series(dic)/100)).combine_first(df)[df.columns]
    else choice == monthly : 
        df["month"] = df.date.dt.month           
        df = (df+df.select_dtypes(include =                   
        'number').mul(pd.Series(dic)/100)).combine_first(df)[df.columns]
    return df

【问题讨论】:

  • 这不是代码编写或辅导服务。我们可以帮助解决具体的技术问题,而不是对代码或建议的开放式请求。请编辑您的问题以显示您迄今为止尝试过的内容,以及您需要帮助的具体问题。详情请见:Why is Can someone help me? not an actual question?
  • 我确实尝试过在现有的 pandas 数据框中进行年度更新,并且它有效,我预先编写了它。我只想按月(在带有时间戳的指定列中更改 12 个百分比值)和季度级别(在带有时间戳的指定列中更改 4 个百分比值)执行此操作。 p.s.我没有要求任何辅导,我只需要一些帮助。祝你有美好的一天:)
  • 您的编码尝试在哪里,您遇到了什么具体问题。请为您的问题提供完整的相关Minimal Reproducible Example
  • 请在您的问题中发布您的代码。编辑问题并添加代码。
  • @itprorh66 现在对你有用吗?

标签: python pandas dataframe data-manipulation data-munging


【解决方案1】:

当然可能有一种更简洁的方法,但以下方法会起作用,并提供单一功能来进行年度、季度或月度更新,如下所示:

import pandas as pd
from collections import namedtuple

# Control tuple defining the date parameters for changing dataframe
DateControl = namedtuple('DateControl', ['Year', 'Quarter', 'Month'])


def updateFrame(df:pd.DataFrame, pcnt_val: float, **args) -> pd.DataFrame:
    # Function to update a specified year, quarter of Month by pcnt_val amount
    dtecol = args.pop('DTECOL', None)
    colList = args.pop('Columns', [])
    control = DateControl(args.pop('Year', None),
                          args.pop('Quarter', None),
                          args.pop('Month', None)
                         )
    
    def EvalDate(ds: pd.Series, row: int, selection: DateControl) -> bool:
        # Evaluate the truth of a date based on control arguments
        yr = False
        qtr = False
        mnth = False
        if selection.Year is None:
            yr = True
        else:
            if ds[row].year == selection.Year:
                yr = True
        if selection.Quarter is None:
            qtr = True
        else:
            if ds[row].quarter == selection.Quarter:
                qtr = True
        if selection.Month is None:
            mnth = True
        else:
            if ds[row].month == selection.Month:
                mnth = True
        return yr and qtr and mnth
    
    # Use control to update all cols named in colList
    mask = list(EvalDate(df[dtecol], x, control) for x in range(len(df[dtecol])))
    mod = list((1.0 + pcnt_val) if x else 1.0 for x in mask)
    print(mask)
    print(mod)
    for c in colList:
         df[c] = list(df.iloc[x][c] * mod[x] for x in range(len(df[c])))     
    return df    

updateFrame 函数接受两个位置参数:
. df - 要更新的数据框
. pcnt_val - 要添加到当前值的百分比

该函数还需要包含一些关键字变量:

  • DTECOL - 这是包含日期的 df 列的名称
  • Columns - Df 中要更改的列标题列表
  • Year - 年份值,如果要更改所有年份,则为 None
  • 四分之一 - 一个特定的四分之一整数 1 到 4 (含)或无
  • 月份 - 要更改的特定月份或无

将此函数应用于您的数据框 df,如下所示:

dg = updateFrame(df, .25, DTECOL='Date', Columns=['Col_1', 'Col_2'], Year=2021, Quarter=3)  

产量:

    Date    Col_1   Col_2   Col_3   Col_4   Col_5
0   2021-01-01  10.0    20.0    10  20  10
1   2021-02-01  10.0    20.0    10  20  10
2   2021-03-01  10.0    20.0    10  20  10
3   2021-04-01  10.0    20.0    10  20  10
4   2021-05-01  10.0    20.0    10  20  10
5   2021-06-01  10.0    20.0    10  20  10
6   2021-07-01  12.5    25.0    10  20  10
7   2021-08-01  12.5    25.0    10  20  10
8   2021-09-01  12.5    25.0    10  20  10
9   2021-10-01  10.0    20.0    10  20  10
10  2021-11-01  10.0    20.0    10  20  10
11  2021-12-01  10.0    20.0    10  20  10

鉴于您想在一次通话中提供所有 4 个季度的更新,我会这样做: 添加新功能:

def updateByQuarter(df:pd.DataFrame, changes: list, **args) -> pd.DataFrame:
    #  Given a quarterly change list of the form tuple(qtrid, chgval) Update the dataframe
    for chg in changes:
        args['Quarter'] = chg[0]
        df updateFrame(df, chg[1], **args)
    return df    

然后按季度创建更改列表

# List of tuples defining the quarter and percent change
qtrChg = [(1, 0.02),(2, 0.035),(3, -0.018),(4, 0.125)]  

用途:

df = updateByQuarter(df, [(1, 0.02), (2, 0.04), (3, -0.02), (4, 0.15)], DTECOL='Date', Columns=['Col_1', 'Col_2'])  

这会产生:

         Date  Col_1  Col_2  Col_3  Col_4  Col_5
0  2021-01-01   10.2   20.4     10     20     10
1  2021-02-01   10.2   20.4     10     20     10
2  2021-03-01   10.2   20.4     10     20     10
3  2021-04-01   10.4   20.8     10     20     10
4  2021-05-01   10.4   20.8     10     20     10
5  2021-06-01   10.4   20.8     10     20     10
6  2021-07-01    9.8   19.6     10     20     10
7  2021-08-01    9.8   19.6     10     20     10
8  2021-09-01    9.8   19.6     10     20     10
9  2021-10-01   11.5   23.0     10     20     10
10 2021-11-01   11.5   23.0     10     20     10
11 2021-12-01   11.5   23.0     10     20     10

【讨论】:

  • 如果是每月,最多可以增加/减少 12 个月的百分比,对于每月的第 4 季度和第 1 季度也是如此。我怎么能通过这个,我没有很好地理解代码
  • 要创建负百分比变化,请将负值传递为 pcnt_val
  • 哪部分不明白?
  • 另外,如果此答案对您有用,请将其作为答案(帖子左侧的复选标记)。发帖人会根据他们选择的答案获得声望分。
  • 我想为每个季度传递 4 pcnt_val(比如 q1:2%、q2:4%、q3:5%、q4:-1)。我知道如何做到这一点。我是 python 新手,你的代码对我来说似乎太复杂了。我试过了,现在我很困惑
【解决方案2】:

**pandas 捕获了 4 个与时间相关的一般概念:

日期时间:具有时区支持的特定日期和时间。类似于标准库中的 datetime.datetime。

时间增量:绝对持续时间。类似于标准库中的 datetime.timedelta。

时间跨度:由时间点及其相关频率定义的时间跨度。

日期偏移:尊重日历算术的相对持续时间。类似于 dateutil 包中的 dateutil.relativedelta.relativedelta。**

【讨论】:

  • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
猜你喜欢
  • 2021-01-07
  • 2020-11-16
  • 2023-03-31
  • 1970-01-01
  • 2021-03-08
  • 2018-12-20
  • 2020-08-28
  • 2021-05-17
  • 2020-07-16
相关资源
最近更新 更多