【问题标题】:Create a new column that is the sum of the number of dates in multiple other columns that satisfy two conditions创建一个新列,该列是满足两个条件的多个其他列中的日期数之和
【发布时间】:2019-04-19 01:00:50
【问题描述】:

我有一个看起来与此类似的数据框(除了 VisitDeliv 列的数量上升到 Visit_84Deliv 84 并且有数百个客户端 - 我在这里简化了它)

Client   Visit_1    Visit_2    Visit_3    Deliv_1  Deliv_2  Deliv_3 Key_DT
Client_1 2018-01-01 2018-01-20 2018-02-10 No       Yes      Yes     2018-01-15
Client_2 2018-01-10 2018-01-30 2018-02-10 Yes      Yes      No      2018-01-25
Client_3 2018-01-20 2018-04-01 2018-04-10 Yes      Yes      Yes     2018-04-15
Client_4 2018-01-30 2018-03-01 2018-03-10 Yes      No       Yes     2018-02-25

我想创建一个名为 Vis_sum 的新列,它显示从 Visit_1Visit_3 的访问次数的总和,这些访问次数位于同一行中的 Key_DT 之后,并且在关联 Deliv 列(例如,Deliv_1Visit_1 关联)。它应该是这样的

Client   Visit_1    Visit_2    Visit_3    Deliv_1  Deliv_2  Deliv_3 Key_DT     Vis_sum
Client_1 2018-01-01 2018-01-20 2018-02-10 No       Yes      Yes     2018-01-15 2
Client_2 2018-01-10 2018-01-30 2018-02-10 Yes      Yes      No      2018-01-25 1
Client_3 2018-01-20 2018-04-01 2018-04-10 Yes      Yes      Yes     2018-04-15 0
Client_4 2018-01-30 2018-03-01 2018-03-10 Yes      No       Yes     2018-02-25 1

【问题讨论】:

    标签: python pandas datetime


    【解决方案1】:

    这假设您的所有列都是datetime。如果不是,请转换它们。


    设置

    a = df.filter(like='Visit').values
    b = df.filter(like='Deliv').eq('Yes').values
    c = df['Key_DT'].values
    

    使用与广播的比较

    ((a > c[:, None]) & b).sum(1)
    

    array([2, 1, 0, 1])
    

    df.assign(Vis_sum=((a > c[:, None]) & b).sum(1))
    

         Client    Visit_1    Visit_2    Visit_3 Deliv_1 Deliv_2 Deliv_3     Key_DT  Vis_sum
    0  Client_1 2018-01-01 2018-01-20 2018-02-10      No     Yes     Yes 2018-01-15        2
    1  Client_2 2018-01-10 2018-01-30 2018-02-10     Yes     Yes      No 2018-01-25        1
    2  Client_3 2018-01-20 2018-04-01 2018-04-10     Yes     Yes     Yes 2018-04-15        0
    3  Client_4 2018-01-30 2018-03-01 2018-03-10     Yes      No     Yes 2018-02-25        1
    

    【讨论】:

    • 感谢您的帮助。我已经稍微修改了它,因为我还需要只对关键日期超过某个日期的客户执行任务。现在看起来像这样:df.loc[(df.Key_DT > '2018-02-01'), 'Vis_sum']=((a > c[:, None]) & b).sum(1))。但是,此修改后的代码或您提供的原始代码都不起作用。我收到以下错误消息:operands could not be broadcast together with shapes (1537,81) (1537,12)Visit 列、Deliv 列和Key_DT 列中是否都有一些缺失数据?如果是这样,我该如何解决?
    • @FGreen 您需要在创建 abc 时应用与索引 DataFrame 时相同的掩码。所以对于a,它会变成df.filter(like='Visit').loc[df.Key_DT > '2018-02-01'],等等。
    • 谢谢。所以我做了以下更改:a = df.filter(like='Visit').loc[df.Key_DT > '2018-02-01']b = df.filter(like='Deliv').eq('Yes').loc[df.Key_DT > '2018-02-01']c = df['Key_DT'].loc[df.Key_DT > '2018-02-01'] 但是,我仍然收到类似的错误消息:cannot broadcast shape [(13, 81)] with block values [(13, 1)]
    • 修正了一个错误(我使用了错误的“访问”列)——他们现在的错误是cannot broadcast shape [(13, 12)] with block values [(13, 1)]
    【解决方案2】:

    这是np 方法:

    deliv_cols = [col for col in df.columns if 'Deliv' in col]
    visit_cols = [col for col in df.columns if 'Visit' in col]
    
    flags = df[deliv_cols].apply(lambda x: x.str.contains('Y'))
    date_flags = df[visit_cols].apply(lambda x: x>df.Key_DT)
    
    df['Vis_sum'] = np.sum(flags.values & date_flags.values,axis=1)
    

    【讨论】:

    • 如上,我收到类似的错误信息:operands could not be broadcast together with shapes (1537,12) (1537,81)
    • 检查 len(deliv_cols) 和 len(visit_cols)。他们都像声称的那样 84 岁吗?
    • 道歉 - 他们不是。有 84 个visit_cols,但只有 12 个 `deliv_cols'
    • 那么您如何将 84 次访问与 12 次交付联系起来?我的意思是不能是“visit_1 with deliv_1 等等”,对吧?
    • 忽略 - 它们的长度相同,抱歉,12 个访问列,12 个交付列
    猜你喜欢
    • 2019-09-11
    • 2020-09-08
    • 2020-06-02
    • 1970-01-01
    • 1970-01-01
    • 2014-09-19
    • 2019-11-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多