如何将列转换为pandas中的一个日期时间列?

use*_*204 45 datetime python-2.7 pandas

我有一个数据框,前3列是'MONTH','DAY','YEAR'

在每列中都有一个整数.在数据帧中有没有Pythonic方法将所有三列转换为日期时间?

从:

M    D    Y    Apples   Oranges
5    6  1990      12        3
5    7  1990      14        4
5    8  1990      15       34
5    9  1990      23       21
Run Code Online (Sandbox Code Playgroud)

成:

Datetimes    Apples   Oranges
1990-6-5        12        3
1990-7-5        14        4
1990-8-5        15       34
1990-9-5        23       21
Run Code Online (Sandbox Code Playgroud)

jez*_*ael 62

0.18.1您可以使用的版本中to_datetime,但是:

  • 列的名称必须是year,month,day,hour,minutesecond:
  • 最小的列是year,monthday

样品:

import pandas as pd

df = pd.DataFrame({'year': [2015, 2016],
                   'month': [2, 3],
                    'day': [4, 5],
                    'hour': [2, 3],
                    'minute': [10, 30],
                    'second': [21,25]})

print df
   day  hour  minute  month  second  year
0    4     2      10      2      21  2015
1    5     3      30      3      25  2016

print pd.to_datetime(df[['year', 'month', 'day']])
0   2015-02-04
1   2016-03-05
dtype: datetime64[ns]

print pd.to_datetime(df[['year', 'month', 'day', 'hour']])
0   2015-02-04 02:00:00
1   2016-03-05 03:00:00
dtype: datetime64[ns]

print pd.to_datetime(df[['year', 'month', 'day', 'hour', 'minute']])
0   2015-02-04 02:10:00
1   2016-03-05 03:30:00
dtype: datetime64[ns]

print pd.to_datetime(df)
0   2015-02-04 02:10:21
1   2016-03-05 03:30:25
dtype: datetime64[ns]
Run Code Online (Sandbox Code Playgroud)

另一个解决方案是转换为dictionary:

print df
   M  D     Y  Apples  Oranges
0  5  6  1990      12        3
1  5  7  1990      14        4
2  5  8  1990      15       34
3  5  9  1990      23       21

print pd.to_datetime(dict(year=df.Y, month=df.M, day=df.D))
0   1990-05-06
1   1990-05-07
2   1990-05-08
3   1990-05-09
dtype: datetime64[ns]
Run Code Online (Sandbox Code Playgroud)

  • 撇开性能讨论不谈,我发现到“dict”的转换是最容易看到的。 (2认同)

Jef*_*eff 43

在0.13(即将推出)中,这是经过大量优化并且非常快(但在0.12中仍然相当快); 比循环快两个数量级

In [3]: df
Out[3]: 
   M  D     Y  Apples  Oranges
0  5  6  1990      12        3
1  5  7  1990      14        4
2  5  8  1990      15       34
3  5  9  1990      23       21

In [4]: df.dtypes
Out[4]: 
M          int64
D          int64
Y          int64
Apples     int64
Oranges    int64
dtype: object

# in 0.12, use this
In [5]: pd.to_datetime((df.Y*10000+df.M*100+df.D).apply(str),format='%Y%m%d')

# in 0.13 the above or this will work
In [5]: pd.to_datetime(df.Y*10000+df.M*100+df.D,format='%Y%m%d')
Out[5]: 
0   1990-05-06 00:00:00
1   1990-05-07 00:00:00
2   1990-05-08 00:00:00
3   1990-05-09 00:00:00
dtype: datetime64[ns]
Run Code Online (Sandbox Code Playgroud)

  • 这是一个古老的答案,但问题是谷歌排名第一.现在这方面还有新的东西吗? (5认同)
  • 我有兴趣看看你是否从`pd.to_datetime(dict(year = df.Y,month = df.M,day = df.D))得到更好的结果. (3认同)

unu*_*tbu 7

这是一个使用NumPy datetime64和timedelta64算法的替代方法.对于小型DataFrame,它看起来要快一些,对于较大的DataFrame,速度要快得多:

import numpy as np
import pandas as pd

df = pd.DataFrame({'M':[1,2,3,4], 'D':[6,7,8,9], 'Y':[1990,1991,1992,1993]})
#    D  M     Y
# 0  6  1  1990
# 1  7  2  1991
# 2  8  3  1992
# 3  9  4  1993

y = np.array(df['Y']-1970, dtype='<M8[Y]')
m = np.array(df['M']-1, dtype='<m8[M]')
d = np.array(df['D']-1, dtype='<m8[D]')
dates2 = pd.Series(y+m+d)
# 0   1990-01-06
# 1   1991-02-07
# 2   1992-03-08
# 3   1993-04-09
# dtype: datetime64[ns]
Run Code Online (Sandbox Code Playgroud)
In [214]: df = pd.concat([df]*1000)

In [215]: %timeit pd.to_datetime((df['Y']*10000+df['M']*100+df['D']).astype('int'), format='%Y%m%d')
100 loops, best of 3: 4.87 ms per loop

In [216]: %timeit pd.Series(np.array(df['Y']-1970, dtype='<M8[Y]')+np.array(df['M']-1, dtype='<m8[M]')+np.array(df['D']-1, dtype='<m8[D]'))
1000 loops, best of 3: 839 µs per loop
Run Code Online (Sandbox Code Playgroud)

这是一个帮助函数,使这更容易使用:

def combine64(years, months=1, days=1, weeks=None, hours=None, minutes=None,
              seconds=None, milliseconds=None, microseconds=None, nanoseconds=None):
    years = np.asarray(years) - 1970
    months = np.asarray(months) - 1
    days = np.asarray(days) - 1
    types = ('<M8[Y]', '<m8[M]', '<m8[D]', '<m8[W]', '<m8[h]',
             '<m8[m]', '<m8[s]', '<m8[ms]', '<m8[us]', '<m8[ns]')
    vals = (years, months, days, weeks, hours, minutes, seconds,
            milliseconds, microseconds, nanoseconds)
    return sum(np.asarray(v, dtype=t) for t, v in zip(types, vals)
               if v is not None)

In [437]: combine64(df['Y'], df['M'], df['D'])
Out[437]: array(['1990-01-06', '1991-02-07', '1992-03-08', '1993-04-09'], dtype='datetime64[D]')
Run Code Online (Sandbox Code Playgroud)


use*_*204 5

我重新解决了这个问题,我想我找到了解决方案。我通过以下方式初始化了 csv 文件:

pandas_object = DataFrame(read_csv('/Path/to/csv/file', parse_dates=True, index_col = [2,0,1] ))
Run Code Online (Sandbox Code Playgroud)

哪里:

index_col = [2,0,1]
Run Code Online (Sandbox Code Playgroud)

表示[年、月、日]的列

现在唯一的问题是,现在我有了三个新的索引列,一个代表年份,另一个代表月份,另一个代表日期。

  • 试试 `parse_dates=[[2,0,1]]`(注意双括号。看看 `read_csv` 上的文档字符串作为例子。 (4认同)