【问题标题】:Python_Pandas: If datetime values fall under certain date duration, create a column with specific valuePython_Pandas:如果日期时间值低于特定日期持续时间,则创建具有特定值的列
【发布时间】:2018-04-23 09:48:32
【问题描述】:

鉴于:

从df下方,

df = pd.DataFrame(
            {"date":['2016-6-1', '2016-9-22', '2016-10-28', '2016-11-4', '2016-6-29', '2016-10-1', '2016-6-15', '2016-7-29', '2016-11-1'],
             "score":[9, 8, 8, 10, 6, 7, 7, 7, 6]
            })

执行以下任务:

对于满足以下条件的日期,为新添加的名为“staffNumber”的列添加特定值:

IF 'date' 低于 6/1/2016~9/22/2016 THAN 创建一个值为 1 的新列。

IF 'date' 低于 9/23/2016~10/28/2016 THAN 创建一个值为 2 的新列。

IF 'date' 低于 10/29/2016~11/4/2016 THAN 创建一个值为 3 的新列

最终结果如下所示:

df2 = pd.DataFrame(
            {"date":['2016-6-1', '2016-9-22', '2016-10-28', '2016-11-4', '2016-6-29', '2016-10-1', '2016-6-15', '2016-7-29', '2016-11-1'],
             "score":[9, 8, 8, 10, 6, 7, 7, 7, 6],
             "staffNumber":[1,1,2,3,1,2,1,1,3]
            })

我尝试过的:

我通常在问任何问题之前先尝试一下。但是,对于这个,我想不出任何方法。

我从以下链接中查看了使用 np.where 和 .isin: 1.Python numpy where function with datetime 2.Using 'isin' on a date in a pandas column 3.Pandas conditional creation of a series/dataframe column

任何帮助将不胜感激!

【问题讨论】:

    标签: python pandas numpy duration


    【解决方案1】:

    这个问题似乎有点老了,但我最近也有类似的需求,我是这样做的:

    def staffNumber(date):
        if datetime.date(2016, 1, 6) <= date <= datetime.date(2016, 9, 22):
            return 1
        elif datetime.date(2016, 9, 23) <= date <= datetime.date(2016, 10, 28):
            return 2
    
        """#(include all the other IFs and date ranges here)"""
    
        else:
            return 'input date out of range'
    
    df['staffNumber'] = df.date.apply(lambda x: fiscalweek(x) )
    

    【讨论】:

      【解决方案2】:

      使用cut:

      #convert to datetimes if necessary
      df['date'] = pd.to_datetime(df['date'])
      b = pd.to_datetime(['2016-06-01','2016-09-22','2016-10-28','2016-11-04'])
      l = range(1,4)
      df['new'] = pd.cut(df['date'], bins=b, labels=l, include_lowest=True)
      print (df)
              date  score new
      0 2016-06-01      9   1
      1 2016-09-22      8   1
      2 2016-10-28      8   2
      3 2016-11-04     10   3
      4 2016-06-29      6   1
      5 2016-10-01      7   2
      6 2016-06-15      7   1
      7 2016-07-29      7   1
      8 2016-11-01      6   3
      

      numpy.searchsorted:

      #change first date to 2016-05-31
      b = pd.to_datetime(['2016-05-31','2016-09-22','2016-10-28','2016-11-04'])
      l = range(1,4)
      
      df['new'] = np.array(l)[b.searchsorted(df['date'].values) - 1]
      print (df)
              date  score  new
      0 2016-06-01      9    1
      1 2016-09-22      8    1
      2 2016-10-28      8    2
      3 2016-11-04     10    3
      4 2016-06-29      6    1
      5 2016-10-01      7    2
      6 2016-06-15      7    1
      7 2016-07-29      7    1
      8 2016-11-01      6    3
      

      【讨论】:

      • 它适用于示例 df。但是对于我必须解决的问题,我有 16 个不同的日期范围,6/1/2016~Now,所有这些范围都有不同的值 (1,2,1,0,1,0,1,0,-1 ,-2,-3,-4,-4,-3,-2,-3)。第一种方法 'cut' 方法不适用于 ValueError:分类类别必须是唯一的。我正在尝试第二种方法。但是,您在第二种方法中在哪里应用了 range(1,4) ?另一个问题是我的问题也有负数..
      • 我编辑答案,只使用从searchosrted函数返回的索引索引l,负数也很好用。
      【解决方案3】:

      一般来说,完成这个你需要创建一个列而不考虑日期的值。

      df['employee'] = ...some_value_here...
      

      然后您需要在日期在您指定的范围内时分配值。你可以用 lambda 来做到这一点:

      df['employee'] = df['date'].apply( lambda x : __something__ )
      

      现在您已将 lambda 中的 __something__ 替换为将日期范围(它们是字符串!)分配到您需要的值的逻辑。

      如果 lambda 中的 __something__ 很长,它将不可读:定义一个之前执行此操作的函数并应用(lambda x: justdefinedfunction(x) )

      【讨论】:

        猜你喜欢
        • 2017-08-25
        • 2018-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多