Numpy 将时间戳/日期时间更改为整数

问题描述 投票:0回答:4

与其说是一个问题,不如说是一些让我困惑的事情。

我有一列日期,看起来像这样:

0              NaT
1       1996-04-01
2       2000-03-01
3              NaT
4              NaT
5              NaT
6              NaT
7              NaT
8              NaT

我想将 NaT 转换为静态值。 (假设我将 pandas 导入为 pd,将 numpy 导入为 np)。

如果我这样做:

mydata['mynewdate'] = mydata.mydate.replace(
    np.NaN, pd.datetime(1994,6,30,0,0))

一切都很好,我明白:

0       1994-06-30
1       1996-04-01
2       2000-03-01
3       1994-06-30
4       1994-06-30
5       1994-06-30
6       1994-06-30
7       1994-06-30
8       1994-06-30

但是如果我这样做:

mydata['mynewdate'] = np.where(
    mydata['mydate'].isnull(), pd.datetime(1994,6,30,0,0),mydata['mydate'])

我得到:

0        1994-06-30 00:00:00
1         828316800000000000
2         951868800000000000
3        1994-06-30 00:00:00
4        1994-06-30 00:00:00
5        1994-06-30 00:00:00
6        1994-06-30 00:00:00
7        1994-06-30 00:00:00
8        1994-06-30 00:00:00

此操作将原始的非空日期转换为整数。我认为可能存在数据类型的混淆,所以我这样做了:

mydata['mynewdate'] = np.where(
    mydata['mydate'].isnull(), pd.datetime(1994,6,30,0,0),pd.to_datetime(mydata['mydate']))

仍然得到:

0        1994-06-30 00:00:00
1         828316800000000000
2         951868800000000000
3        1994-06-30 00:00:00
4        1994-06-30 00:00:00
5        1994-06-30 00:00:00
6        1994-06-30 00:00:00
7        1994-06-30 00:00:00
8        1994-06-30 00:00:00

请注意(不要问):是的,我有一个更好的解决方案来替换空值。这个问题不是关于替换空值(正如标题所示),而是关于 numpy where 处理日期的方式。我问这个问题是因为我将来会有更复杂的条件来选择要替换的日期,并且认为 numpy 在哪里可以完成这项工作。

有什么想法吗?

python pandas numpy datetime where-clause
4个回答
9
投票

这是由于 Numpy 的

datetime64
、Pandas 的
Timestamp
和/或
datetime.datetime
之间的不稳定交互造成的。我通过从一开始就将替换值设置为
numpy.datetime64
来修复它。

static_date = np.datetime64('1994-06-30')
# static_date = np.datetime64(pd.datetime(1994, 6, 30))

mydata.assign(
    mynewdate=np.where(
        mydata.mydate.isnull(),
        static_date,
        mydata.mydate
    )
)

      mydate  mynewdate
0        NaT 1994-06-30
1 1996-04-01 1996-04-01
2 2000-03-01 2000-03-01
3        NaT 1994-06-30
4        NaT 1994-06-30
5        NaT 1994-06-30
6        NaT 1994-06-30
7        NaT 1994-06-30
8        NaT 1994-06-30

2
投票

如果您在

pandas
,请尝试使用
mask/where
中的
pandas

df.mask(df['Date'].isnull(), pd.to_datetime('1994-06-30'))
Out[824]: 
        Date
0 1994-06-30
1 1996-04-01
2 2000-03-01
3 1994-06-30
4 1994-06-30
5 1994-06-30
6 1994-06-30
7 1994-06-30
8 1994-06-30

0
投票

一个选项是使用列表理解,如下所示应该可以:

mydata['mynewdate'] = [pd.datetime(1994,6,30,0,0) if pd.isna(mydata.loc[j,'mydate']) else mydata.loc[j,'mydate'] for j in mydata.index]

0
投票

刚刚遇到了一个非常相似的问题(我使用了 numpy 的

.where()
函数,但问题本身是相同的)。我不知道为什么会这样,但它确实有效(下面解释了一个警告):

原代码:

df['date']  = np.where(df['date'].between(df['start'], df['end']), df['date'], None)

但这导致了一个带有纳秒日期的“日期”列(例如1656374400000000000)

更新代码:

df['date']  = np.where(df['date'].between(df['start'], df['end']), df['date'].astype(str), None)

唯一的区别是最后的

astype(str)
位。这返回了我开始时采用的“YYYY-mm-dd”格式的日期。

这里需要注意的是,以前的 datetime.datetime 数据类型已转换为字符串,但转换回来非常容易,我什至可以通过将整个数据包装在

pd.to_datetime()
函数中来在线完成它,但是为了清楚起见,将其留在这里。

© www.soinside.com 2019 - 2024. All rights reserved.