在pandas中处理日期 - 移除datetime中的不可见字符并转换为字符串
我正在使用pandas来导入数据,代码是 dfST = read_csv( ... , parse_dates={'timestamp':[date]})
。在我的csv文件中,日期的格式是YYYY/MM/DD,这正是我需要的——没有时间。我有几个数据集需要比较它们的成员资格。当我把这些'timestamp'转换成字符串时,有时会得到这样的结果:
'1977-07-31T00:00:00.000000000Z'
我知道这表示一个包含毫秒和时区的日期时间格式。有没有办法在导入时不添加这些多余的时间呢?如果不行,我需要想办法把它排除掉。
dfST.timestamp[1]
Out[138]: Timestamp('1977-07-31 00:00:00')
我尝试过格式化它,开始的时候似乎有效,但当我调用这些格式化的值时:
dfSTdate=pd.to_datetime(dfST.timestamp, format="%Y-%m-%d")
dfSTdate.head()
Out[123]:
0 1977-07-31
1 1977-07-31
Name: timestamp, dtype: datetime64[ns]
结果却不是这样……当我测试这个值时,我还是得到了时间:
dfSTdate[1]
Out[124]: Timestamp('1977-07-31 00:00:00')
当我把它转换成数组时,时间也包括在内,还有毫秒和时区,这真的搞乱了我的比较。
test97=np.array(dfSTdate)
test97[1]
Out[136]: numpy.datetime64('1977-07-30T20:00:00.000000000-0400')
我该如何去掉时间呢!?最终我希望使用 numpy.in1d
来比较数据集中的成员资格,把日期作为字符串('YYYY-MM-DD')作为比较的一部分。
1 个回答
这是因为在pandas中,datetime
值的存储方式:使用的是numpy的datetime64[ns]
类型。所以,datetime值总是以纳秒为单位存储。即使你只有日期,这也会被转换成一个时间戳,时间部分为零,精度也是纳秒。这是pandas的实现方式决定的。
你在打印这些值时遇到的问题,以及得到意外结果,都是因为这些对象在python控制台中的显示方式(它们的表示),而不是它们的实际值。
如果你打印一个单独的值,你会得到pandas的Timestamp
表示:
Timestamp('1977-07-31 00:00:00')
所以这里也会显示秒数,这只是默认的显示方式。
如果你把它转换成数组,然后打印,你会得到标准的numpy表示:
numpy.datetime64('1977-07-30T20:00:00.000000000-0400')
这确实是一个非常容易误解的表示方式。因为numpy在控制台打印时,会将其转换为你的本地时区。但这并不会改变你的实际值,只是打印方式有点奇怪。
这就是背景,现在来回答你的问题,如何去掉时间部分?
这取决于你的目标。你真的想把它转换成字符串吗?还是只是对这种表示方式不满意?
如果你只是想处理datetime值,其实不需要去掉时间部分。
如果你想把它转换成字符串,可以使用
strftime
(df['timestamp'].apply(lambda x: x.strftime('%Y-%m-%d'))
)。或者如果是要把它作为字符串写入csv,可以在to_csv
中使用date_format
关键字。如果你真的想要一个“日期”,可以在DataFrame的列中使用
datetime.date
类型(标准的python类型)。你可以用pd.DatetimeIndex(dfST['timestamp']).date
将现有列转换为这种类型。但我个人认为这样做没有太多好处。