计算给定日期范围内一个月的天数(如Pandas列)

ffdz8vbo  于 2023-03-16  发布在  其他
关注(0)|答案(2)|浏览(192)

这是一个关于计算两个日期之间的天数范围的类似问题的转折,这两个日期被划分到每月的列Pandas: monthly date range with number of days中。
在我的数据框中,我有两列df ['begin_date']和df ['end_date']。我想计算特定月份中有多少天。

df['PTO_End_Date'] = pd.to_datetime(df.PTO_End_Date)
df['PTO_Start_Date'] = pd.to_datetime(df.PTO_Start_Date)

df['Days'] = (df['PTO_End_Date'] - df['PTO_Start_Date']).dt.days
df['Feb-2023'] =
df['Mar-2023'] =
df['Apr-2023'] =

我可以计算日期之间的天数,但日期跨越多个月,我试图将日期划分到特定的月份。正在寻找一种方法将此系列样式代码转换为Pandas列。

s = pd.Series(index=pd.date_range(df['PTO_Start_Date'], df['PTO_End_Date']), dtype='float64')
mznpcxlj

mznpcxlj1#

@亚瑟假设你有100条记录,那么最好为每条记录创建一个DataFrame。虽然这需要更多的代码。但这是可行的。
你可以利用几个函数,比如df.pipe()来传递函数。
这个例子有20个日期,但它可以缩放到任何数字。

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'start': [
        '2023-03-15', '2023-04-11', '2023-04-26', '2023-05-05', '2023-06-19',
        '2023-07-04', '2023-07-24', '2023-08-01', '2023-08-21', '2023-09-07'
    ],
    'end': [
        '2023-09-22', '2023-10-05', '2023-10-12', '2023-10-19', '2023-11-20',
        '2023-11-23', '2023-11-30', '2023-12-08', '2023-12-11', '2023-12-13'
    ]
})

def monthly_pto_days_per_range(start_date: str, end_date: str) -> pd.DataFrame:
    dates = pd.Series(
        {"start": pd.to_datetime(start_date), "end": pd.to_datetime(end_date)}
    )
    return (
        (
            pd.Series(
                index=pd.date_range(start=dates["start"], end=dates["end"]),
                dtype="float64",
            )
            .resample("M")
            .size()
            .to_period("M")
            .to_frame()
            .T
        )
        .assign(start_date=start_date, end_date=end_date)
    )
def col_to_front(df: pd.DataFrame, column: str) -> pd.DataFrame:
    r"""
    Bring column to front in a DataFrame.

    Parameters
    ----------
    df : pd.DataFrame

    col : str
        Column to move

    front : bool, optional
        by default True will bring column to position 0
        else to last column
    """
    return df.loc[
        :, lambda x: sorted(x.columns, key=lambda col: 0 if col == column else 1)
    ]

def generate_pto_days_from_date_ranges(DF: pd.DataFrame) -> pd.DataFrame:
    return (
        pd.concat(
            [
                np.vectorize(monthly_pto_days_per_range)(DF["start"], DF["end"])[i]
                for i in df.index
            ]
        )
        .fillna(0)
        .pipe(col_to_front, "end_date")
        .pipe(col_to_front, "start_date")
    )

df.pipe(generate_pto_days_from_date_ranges)

6yt4nkrj

6yt4nkrj2#

有一个完整的代码在这里:

import pandas as pd
from datetime import datetime

df = pd.read_csv(filename, encoding='utf-8')
df.columns = [c.replace(' ','_') for c in df.columns]

# Select columns for dataframe
df = df[['Col1', 'Col2', 'Col3', 'PTO_Start_Date', 'PTO_End_Date']]

# Convert to datetime
df['PTO_Start_Date'] = pd.to_datetime(df.PTO_Start_Date)
df['PTO_End_Date'] = pd.to_datetime(df.PTO_End_Date)

results = df.join(
    df.apply(lambda df: pd.Series(pd.date_range(df['PTO_Start_Date'], df['PTO_End_Date'], freq='B').to_period('M')), axis=1)
    .apply(pd.value_counts, axis=1)
    .fillna(0)
    .astype(int)
)

df = results

df.to_csv('Newfile.csv', index=False)

这将保留我所有的原始列,并在它们自己的列中添加每月工作日数。Freq =“B”表示工作日,Freq=“D”表示总天数。

相关问题