【问题标题】:Last Day previous Month上个月的最后一天
【发布时间】:2021-12-24 05:07:58
【问题描述】:

我有这个数据框

import pandas as pd

df = pd.DataFrame({'Found':['A','A','A','A','A','B','B','B','B'],
           'Date':['14/10/2021','19/10/2021','29/10/2021','30/09/2021','20/09/2021','20/10/2021','29/10/2021','15/10/2021','10/09/2021'],
           'LastDayMonth':['29/10/2021','29/10/2021','29/10/2021','30/09/2021','30/09/2021','29/10/2021','29/10/2021','29/10/2021','30/09/2021'],
           'Mark':[1,2,3,4,3,1,2,3,2]

          })
print(df)

    Found     Date   LastDayMonth  Mark
0     A  14/10/2021   29/10/2021     1
1     A  19/10/2021   29/10/2021     2
2     A  29/10/2021   29/10/2021     3
3     A  30/09/2021   30/09/2021     4
4     A  20/09/2021   30/09/2021     3
5     B  20/10/2021   29/10/2021     1
6     B  29/10/2021   29/10/2021     2
7     B  15/10/2021   29/10/2021     3
8     B  10/09/2021   30/09/2021     2

基于这个数据框,我需要创建一个新列,它是当月最后一天的“标记”,以形成这个新列。

也就是说,我需要每个Found的当月最后一天的'Mark'列的值

我是怎么做到的

mark_last_day = df.loc[df.apply(lambda x: x['Date']==x['LastDayMonth'], 1)]


df.merge(mark_last_day[['Found', 'LastDayMonth', 'Mark']],
 how='left',
 on=['Found', 'LastDayMonth'],
 suffixes=('', '_LastDayMonth'))

# Output
Found   Date    LastDayMonth    Mark    Mark_LastDayMonth
0   A   14/10/2021  29/10/2021  1       3
1   A   19/10/2021  29/10/2021  2       3
2   A   29/10/2021  29/10/2021  3       3
3   A   30/09/2021  30/09/2021  4       4
4   A   20/09/2021  30/09/2021  3       4 
5   B   20/10/2021  29/10/2021  1       2
6   B   29/10/2021  29/10/2021  2       2
7   B   15/10/2021  29/10/2021  3       2

到目前为止一切顺利,但我无法使用上个月的 Mark_LastDayMonth 创建新列,或者我需要当月的最后一天和上个月 我该怎么做

例如

    Found   Date    LastDayMonth    Mark    Mark_LastDayMonth    Mark_LastDayPrevious_Month
0     A  14/10/2021   29/10/2021     1       3                     4
1     A  19/10/2021   29/10/2021     2       3                     4
2     A  29/10/2021   29/10/2021     3       3                     4
3     A  30/09/2021   30/09/2021     4       4                     x
4     A  20/09/2021   30/09/2021     3       4                     x
5     B  20/10/2021   29/10/2021     1       2                     1
6     B  29/10/2021   29/10/2021     2       2                     1
7     B  15/10/2021   29/10/2021     3       2                     1
8     B  10/09/2021   30/09/2021     1       1                     x

【问题讨论】:

  • 你能给出你是怎么做的逻辑吗?我们只是无法从代码中看出您在做什么以及您想要什么
  • 我需要使用上个月最后一天的“标记”创建一个新列,我得到了代码中显示的当前月份
  • 您可能需要将您的字符串日期转换为日期时间类型,然后移动月份...

标签: python-3.x pandas datetime


【解决方案1】:

这是一个获取上个月最后一天的函数

import datetime

def get_prev_month(date_str):
    format_str = '%d/%m/%Y'
    datetime_obj = datetime.datetime.strptime(date_str, format_str)
    first_day_of_this_month = datetime_obj.replace(day=1)
    last_day_of_prev_month = first_day_of_this_month - datetime.timedelta(days=1)
    return last_day_of_prev_month.strftime("%d/%m/%Y")

这是一个从你的 mark_last_day 变量中获取任何“日期”和“找到”标记的函数

def get_mark_of(date_str, found):
    same_date = last_day_mark.Date==date_str
    same_found = last_day_mark.Found == found
    return last_day_mark.where(same_date & same_found).dropna().Mark

如果您想添加 LastDayPrevMonth 列除非您需要,否则您不需要这样做

df["LastDayPrevMonth"] = df.LastDayMonth.apply(lambda x: get_prev_month(x))

最后创建列 Mark_LastDayPrevMonth,如果数据集中不存在上个月,则设置为 0。

df["Mark_LastDayPrevMonth"] = df.apply(lambda x: get_mark_of(get_prev_month(x["LastDayMonth"]), x["Found"]), axis=1).fillna(0).astype(int)

【讨论】:

  • 哪个是 Mark_last_day ? NameError: name 'mark_last_day' 未定义
  • mark_last_day 是你用来保存这个 df => df.loc[df.apply(lambda x: x['Date']==x['LastDayMonth'], 1)] 的变量。它在您的代码中,执行合并之前的一行。
  • 我忘记了那个细节...但是在 Found B 上它仍然填写数字 4,在这种情况下,这不是我想要的数字,它可能是 3 或 0。我我无法解决这部分
  • 在这种情况下,我已经修改了 get_mark_of 函数以考虑属性“found”!希望现在一切就绪。
【解决方案2】:

使用日期偏移量MonthEnd

from pandas.tseries.offsets import MonthEnd

df['LastDayPreviousMonth'] = df['Date'] - MonthEnd()

>>> df[['Date', 'LastDayPreviousMonth']]

        Date LastDayPreviousMonth
0 2021-10-14           2021-09-30
1 2021-10-19           2021-09-30
2 2021-10-29           2021-09-30
3 2021-09-30           2021-08-31
4 2021-09-20           2021-08-31
5 2021-10-20           2021-09-30
6 2021-10-29           2021-09-30
7 2021-10-15           2021-09-30

然后进行与“LastDayMonth”类似的合并。

这是否有助于您完成解决方案?

注意:我假设 'Date' 和 'LastDayPreviousMonth' 类似于日期时间。如果不是,您需要先使用转换它们

df[['Date', 'LastDayMonth']] = df[['Date', 'LastDayMonth']].apply(pd.to_datetime)

【讨论】:

  • 然后我创建一个列,如示例中的'Mark' LastDayPreviousMonth'
  • 我的问题不在于月份,而在于上个月的“标记”
  • @EricAlves 对不起,我不明白你的意思。这能解决您的问题吗?还是您需要完整的解决方案?
猜你喜欢
  • 1970-01-01
  • 2017-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-03
  • 2013-11-25
相关资源
最近更新 更多