Python在Pandas中清洗日期以仅转换为年份

4 投票
1 回答
8781 浏览
提问于 2025-04-18 10:08
"ValueError: Error parsing datetime string ""03/13/2014"" at position 2"

我有一个很大的数据集,有些用户在一个CSV文件中输入了数据。我用panda把这个CSV转换成了一个数据框(dataframe)。这个数据框的某一列有超过1000条数据,下面是一个样本:

datestart
5/5/2013
6/12/2013
11/9/2011
4/11/2013
10/16/2011
6/15/2013
6/19/2013
6/16/2013
10/1/2011
1/8/2013
7/15/2013
7/22/2013
7/22/2013
5/5/2013
7/12/2013
7/29/2013
8/1/2013
7/22/2013
3/15/2013
6/17/2013
7/9/2013
3/5/2013
5/10/2013
5/15/2013
6/30/2013
6/30/2013
1/1/2006
00/00/0000
7/1/2013
12/21/2009
8/14/2013
Feb 1 2013

然后我尝试把日期转换成年份,使用了:

df['year']=df['datestart'].astype('timedelta64[Y]')

但是出现了一个错误:

ValueError: Value cannot be converted into object Numpy Time delta

使用Datetime64时,结果是:

df['year']=pd.to_datetime(df['datestart']).astype('datetime64[Y]')

因为那一列是用户填写的,大部分数据的格式是MM/DD/YYYY,但有些数据是这样填写的:Feb 10 2013,还有一条数据是00/00/0000。我猜测不同的格式搞乱了处理过程。

有没有什么try loopif statement之类的东西,可以让我跳过这些问题呢?

如果日期时间处理失败,我就得用str.extract脚本,这个方法也能用:

year=df['datestart'].str.extract("(?P<month>[0-9]+)(-|\/)(?P<day>[0-9]+)(-|\/)(?P<year>[0-9]+)")


del df['month'], df['day']  

然后用concat来提取年份。

df['year']=pd.to_datetime(df['datestart'],coerce=True, errors ='ignore').astype('datetime64[Y]')时,错误信息是:

Message File Name   Line    Position    
Traceback               
    <module>    C:\Users\0\Desktop\python\Example.py    23      
    astype  C:\Python33\lib\site-packages\pandas\core\generic.py    2062        
    astype  C:\Python33\lib\site-packages\pandas\core\internals.py  2491        
    apply   C:\Python33\lib\site-packages\pandas\core\internals.py  3728        
    astype  C:\Python33\lib\site-packages\pandas\core\internals.py  1746        
    _astype C:\Python33\lib\site-packages\pandas\core\internals.py  470     
    _astype_nansafe C:\Python33\lib\site-packages\pandas\core\common.py 2222        
TypeError: cannot astype a datetimelike from [datetime64[ns]] to [datetime64[Y]]        

1 个回答

5

首先,你需要把包含日期的那一列转换成日期时间格式,可以用 to_datetime() 这个函数:

df['datestart'] = pd.to_datetime(df['datestart'], coerce=True)

这个函数通常能灵活地解析不同的日期格式(这里的 coerce=True 很重要,它可以把无效的日期转换成 NaT)。

如果你想提取日期中的年份部分,可以这样做(直接对 pandas 的列使用 astype 会出错,但用 values 可以获取底层的 numpy 数组):

df['datestart'].values.astype('datetime64[Y]')

不过这样做会在赋值给某一列时再次出错,因为有 NaT 的值(这似乎是个bug,你可以通过 df = df.dropna() 来解决)。而且,当你把这个赋值给一列时,它会被转换回 datetime64[ns] 格式,因为 pandas 是这样存储日期时间的。所以我个人认为,如果你想要一列年份,最好这样做:

df['year'] =  pd.DatetimeIndex(df['datestart']).year

这样做最后会返回年份,格式是整数。

撰写回答