【问题标题】:Python Pandas Add Value to Multiple Rows Based on DatePython Pandas 根据日期向多行添加值
【发布时间】:2021-09-08 21:04:18
【问题描述】:

我需要仅使用 PythonPandas 解决数据科学问题,其中给定的输入是入住日期、退房日期和付款一个人的每一本书

check_in   check_out  payment
2020-02-28 2020-03-02 66
2020-02-27 2020-02-29 100

我需要显示我之前从那 2 本书中获得的每日收入。我的想法是,我必须为每个日期(如 66/3)拆分它,并将其从 02-28 分配到 03-02 和 100/2,然后将其从 02-27 分配到 02-29 进行第二次订购,然后我会得到这样的结果

date       earnings
2020-02-27 50
2020-02-28 22+50
2020-02-29 22
2020-03-01 22

如果我把它们总结起来会是这样的

date       earnings
2020-02-27 50
2020-02-28 72
2020-02-29 22
2020-03-01 22

我已经将付款列与输入分开,并创建了一个新的数据框,其中包含两个新列,分别代表客人使用 day_stay 停留了多长时间以及我使用 daily_earn 获得了多少收入 使用下面的代码

df["date_stay"] = abs(df["check_in"] - df["check_out"]) # Get difference
df["date_stay"] = pd.to_numeric(df["date_stay"].dt.days) # Turn to days
df["daily_earn"] = df["payment"]/df["date_stay"]

那么结果会是这样的

check_in   check_out  payment day_stay daily_earn
2020-02-28 2020-03-02 66      3        22
2020-02-27 2020-02-29 100     2        50

最后一步是将 daily_earn 中的值分配到从 02-27 到 03-01 的相应日期,但我不知道该怎么做。我曾尝试使用 df.groupby("check_in").sum() 但它没有提供所需的输出,因为输入和输出之间的行数不同。有什么想法吗?

【问题讨论】:

    标签: python pandas dataframe date


    【解决方案1】:

    让我们尝试不同的方法:

    df['date'] = df.apply(
        lambda r: pd.date_range(r['check_in'], r['check_out'], closed='left'),
        axis=1)
    
    df = df.explode('date')
    
    df['earnings'] = df['payment'] / df.groupby(level=0)['date'].transform('count')
    
    df = df.groupby('date', as_index=False)['earnings'].agg('sum')
    

    df:

            date  earnings
    0 2020-02-27      50.0
    1 2020-02-28      72.0
    2 2020-02-29      22.0
    3 2020-03-01      22.0
    

    步骤分解:

    applypd.date_range 到每一行以获取开始和结束之间的天数:

    df['date'] = df.apply(
        lambda r: pd.date_range(r['check_in'], r['check_out'], closed='left'),
        axis=1)
    
        check_in  check_out  payment                                                                                         date
    0 2020-02-28 2020-03-02       66  DatetimeIndex(['2020-02-28', '2020-02-29', '2020-03-01'], dtype='datetime64[ns]', freq='D')
    1 2020-02-27 2020-02-29      100                DatetimeIndex(['2020-02-27', '2020-02-28'], dtype='datetime64[ns]', freq='D')
    

    然后将explodedate放入行:

    df = df.explode('date')
    
        check_in  check_out  payment       date
    0 2020-02-28 2020-03-02       66 2020-02-28
    0 2020-02-28 2020-03-02       66 2020-02-29
    0 2020-02-28 2020-03-02       66 2020-03-01
    1 2020-02-27 2020-02-29      100 2020-02-27
    1 2020-02-27 2020-02-29      100 2020-02-28
    

    然后groupby transform计数date得到日期数,用支付除以天数得到每日收益:

    df['earnings'] = df['payment'] / df.groupby(level=0)['date'].transform('count')
    
        check_in  check_out  payment       date  earnings
    0 2020-02-28 2020-03-02       66 2020-02-28      22.0
    0 2020-02-28 2020-03-02       66 2020-02-29      22.0
    0 2020-02-28 2020-03-02       66 2020-03-01      22.0
    1 2020-02-27 2020-02-29      100 2020-02-27      50.0
    1 2020-02-27 2020-02-29      100 2020-02-28      50.0
    

    然后groupby aggdate 上的收入相加得到每个date 的总和:

    df = df.groupby('date', as_index=False)['earnings'].agg('sum')
    
            date  earnings
    0 2020-02-27      50.0
    1 2020-02-28      72.0
    2 2020-02-29      22.0
    3 2020-03-01      22.0
    

    使用的数据帧和导入:

    import pandas as pd
    
    df = pd.DataFrame({'check_in': {0: '2020-02-28', 1: '2020-02-27'},
                       'check_out': {0: '2020-03-02', 1: '2020-02-29'},
                       'payment': {0: 66, 1: 100}})
    df['check_in'] = pd.to_datetime(df['check_in'])
    df['check_out'] = pd.to_datetime(df['check_out'])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-20
      • 2015-04-22
      • 2021-12-25
      • 2017-05-20
      • 2021-08-26
      • 2020-03-10
      • 1970-01-01
      相关资源
      最近更新 更多