【问题标题】:date calculation (TypeError: unsupported operand type(s) for -: 'str' and 'str')日期计算(TypeError:不支持的操作数类型 -:'str' 和 'str')
【发布时间】:2017-08-07 07:52:27
【问题描述】:

我有一个数据集如下:

        date_time       srch_co     srch_ci
0   2014-11-03 16:02:28 2014-12-19  2014-12-15
1   2013-03-13 19:25:01 2013-03-14  2013-03-13
2   2014-10-13 13:20:25 2015-04-10  2015-04-03
3   2013-11-05 10:40:34 2013-11-08  2013-11-07
4   2014-06-10 13:34:56 2014-08-08  2014-08-03
5   2014-12-16 14:34:39 2014-12-17  2014-12-16

这是数据集的信息:

     <class 'pandas.core.frame.DataFrame'>
RangeIndex: 100000 entries, 0 to 99999
Data columns (total 3 columns):
date_time    100000 non-null datetime64[ns]
srch_co      99878 non-null object
srch_ci      99878 non-null object
dtypes: datetime64[ns](1), object(2)
memory usage: 2.3+ MB

我想做的是使用以下函数创建 2 个新列:

def duration(row):
    delta = (row['srch_co'] - row['srch_ci'])/np.timedelta64(1, 'D')
    if delta <= 0:
        return np.nan
    else:
        return delta

sample['duration'] = sample.apply(duration, axis=1)


def days_in_advance(row):
    delta = (row['srch_ci'] - row['date_time'])/np.timedelta64(1, 'D')
    if delta < 0:
        return np.nan
    else:
        return delta

sample['days_in_advance'] = sample.apply(days_in_advance, axis=1)

但是,我想要运行的日期计算似乎经常遇到错误。我已经搜索并找到了几种解决方案并进行了尝试,但它们要么会产生错误,要么会将日期变成不准确的值。

我尝试过的方法如下:

#1)
def to_integer(dt_time):
    return 10000*dt_time.year + 100*dt_time.month + dt_time.day

#2)
datetime.strptime(str(row[2]), '%Y%m%d%H%M%S')

#3)    
pd.to_numeric(sample['date_time'], errors='coerce')

#4)
sample['srch_ci_int'] = sample['srch_ci'].astype(str).astype(int)

我只想创建一个新列来计算每列的差异:

sample["duration"] = sample["srch_co"] - sample["srch_ci"]
sample["days_in_advance"] = sample["srch_co"] - sample["date_time"]

感谢任何提示。

【问题讨论】:

  • 根据我们这里的信息,我认为简单地将列 srch_* 转换为 datetime 对象可能会有所帮助。
  • 对,我不知道为什么我没有考虑过。谢谢! sample['srch_co'] = pd.to_datetime(sample['srch_co']) sample['srch_ci'] = pd.to_datetime(sample['srch_ci']) 这行得通。

标签: python


【解决方案1】:

您需要先转换列srch_cosrch_ci to_datetime,然后使用mask 将小于0 的值替换为NaNmask 函数的默认值):

sample["srch_co"] = pd.to_datetime(sample["srch_co"])
sample["srch_ci"] = pd.to_datetime(sample["srch_ci"])

sample["duration"] = (sample["srch_co"] - sample["srch_ci"])/np.timedelta64(1, 'D')
sample["days_in_advance"] = (sample["srch_co"] - sample["date_time"])/np.timedelta64(1, 'D')

cols = ['duration','days_in_advance']
sample[cols] = sample[cols].mask(sample[cols] < 0)
#first value of srch_ci column was changed for NaN output
print (sample)
            date_time    srch_co    srch_ci  duration  days_in_advance
0 2014-11-03 16:02:28 2014-12-19 2015-12-15       NaN        45.331620
1 2013-03-13 19:25:01 2013-03-14 2013-03-13       1.0         0.190961
2 2014-10-13 13:20:25 2015-04-10 2015-04-03       7.0       178.444155
3 2013-11-05 10:40:34 2013-11-08 2013-11-07       1.0         2.555162
4 2014-06-10 13:34:56 2014-08-08 2014-08-03       5.0        58.434074
5 2014-12-16 14:34:39 2014-12-17 2014-12-16       1.0         0.392604

【讨论】:

    【解决方案2】:

    好像你是从一个字符串中减去一个字符串。确保使用pd.to_datetime 将该列转换为“日期”类型,然后您就可以从另一天减去一天。

    另一个建议是避免 for 循环并使用矢量化操作,例如 pd.DataFrame.subtract(series, axis=0),因为这是使用 pandas 优于任何简单列表的最大优势之一。

    计算完差值后,你可以通过说把所有的否定变成nan

    dataframe[dataframe['duration'] < 0] = np.nan
    

    【讨论】:

      猜你喜欢
      • 2013-02-20
      • 2018-12-06
      • 1970-01-01
      • 2021-01-03
      • 2018-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多