簡體   English   中英

生成兩個日期列之間的所有月份

[英]Generate all Months between two dates column

我正在嘗試生成兩個日期列之間的所有月份。 我有以下 dataframe:

開始日期 結束日期
01-15-2010 08-15-2010
07-01-2009 01-13-2010

我想要的輸出是添加一個月份列,其中包括 StartDate 和 EndDate 列之間可用的所有月份。

Output:

開始日期 結束日期
01-15-2010 08-15-2010 1,2,3,4,5,6,7,8
07-01-2009 01-13-2010 7,8,9,10,11,12,1

我嘗試編寫這段代碼,但它沒有按我想要的那樣工作。

date_range= lambda x:range (x['StartDate'].month,x['EndDate'].month+1)
df=df.assign(month=df.apply(date_range, axis=1)

我們可以使用dateutil.rrule來做到這一點

代碼:

from dateutil.rrule import rrule, MONTHLY
def month_between_dates(start_date, end_date):
    months_between = [str(dt.month) for dt in rrule(MONTHLY, 
                                dtstart = start_date.replace(day=1), 
                                until = end_date.replace(day=1))]
    return ",".join(months_between)
in_df["Month"] = in_df.apply(lambda x: month_between_dates(x["StartDate"],
                                                           x["EndDate"]), axis=1)

Output:

StartDate    EndDate            Month
2010-01-15 2010-08-15  1,2,3,4,5,6,7,8
2009-07-01 2010-01-15 7,8,9,10,11,12,1

代碼解釋:

months_between = [str(dt.month) for dt in rrule(MONTHLY, 
                            dtstart = start_date.replace(day=1), 
                            until = end_date.replace(day=1))]

start_date.replace(day=1)將日期轉換為第一天。

for dt in rrule(MONTHLY, dtstart = start_date,until = end_date)在開始日期和結束日期之間的月份中迭代。

通過Series.dt.to_period創建帶有日期時間的月份周期,然后使用提取月份為每個壓縮Series創建period_range

s = pd.to_datetime(df['StartDate']).dt.to_period('m')
e = pd.to_datetime(df['EndDate']).dt.to_period('m')

df=df.assign(month=[pd.period_range(y, x).month.tolist() for x, y in zip(e, s)])

print (df)
    StartDate     EndDate                     month
0  01-15-2010  08-15-2010  [1, 2, 3, 4, 5, 6, 7, 8]
1  07-01-2009  01-13-2010  [7, 8, 9, 10, 11, 12, 1]

如果需要由 連接的字符串,請使用:

df=df.assign(month=[','.join(pd.period_range(y, x).month.astype(str)) 
                    for x, y in zip(e, s)])

print (df)
    StartDate     EndDate             month
0  01-15-2010  08-15-2010   1,2,3,4,5,6,7,8
1  07-01-2009  01-13-2010  7,8,9,10,11,12,1

這是基於僅使用pandas.date_rangenumpy.vectorize的矢量解決方案

import numpy as np
import pandas as pd

input_df = pd.DataFrame(
    {
        'StartDate': ['01-15-2010', '07-01-2009'],
        'EndDate': ['08-15-2010', '01-13-2010']
    }
)
input_df = input_df.apply(pd.to_datetime)


def create_months_between(from_timestmp: pd.Timestamp, to_timestamp: pd.Timestamp, return_string=False) -> str:
    """returns a list of months between dates

    Args:
        from_timestmp (pd.Timestamp): datetime from
        to_timestamp (pd.Timestamp): datetime to
        return_string (bool, optional): Retrun a string of months, not a list. Defaults to False.

    Returns:
        str: list of ints if return_string==False, string of values if return_string==True
    """

    list_result = [value.month
                   for value
                   in pd.date_range(
                       from_timestmp,
                       to_timestamp,
                       freq='M',
                       normalize=True
                   )
                   ]
    list_result.append(np.datetime64(to_timestamp).astype(
        'datetime64[M]').astype(int) % 12 + 1)

    result_string = ','.join([str(value) for value in list_result])
    return result_string


input_df.columns
input_df['Month'] = np.vectorize(create_months_between)(
    input_df['StartDate'], input_df['EndDate'])
input_df

它返回一個表,看起來像你描述的那個。

開始日期 結束日期
2010-01-15 2010-08-15 1,2,3,4,5,6,7,8
2009-07-01 2010-01-13 7,8,9,10,11,12,1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM