与其说是一个问题,不如说是一些让我困惑的事情。
我有一列日期,看起来像这样:
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 在哪里可以完成这项工作。
有什么想法吗?
这是由于 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
如果您在
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
一个选项是使用列表理解,如下所示应该可以:
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]
刚刚遇到了一个非常相似的问题(我使用了 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()
函数中来在线完成它,但是为了清楚起见,将其留在这里。