Python 如何在pandas中将列转换为一个datetime列?

Python 如何在pandas中将列转换为一个datetime列?,python,pandas,datetime,Python,Pandas,Datetime,我有一个数据框,其中前3列是“月”、“日”、“年” 每列中都有一个整数。 当数据帧中存在时,是否有一种Pythonic方法将所有三列转换为日期时间 发件人: 进入: 在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

我有一个数据框,其中前3列是“月”、“日”、“年”

每列中都有一个整数。 当数据帧中存在时,是否有一种Pythonic方法将所有三列转换为日期时间

发件人:

进入:

在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]

我重新处理了这个问题,我想我找到了解决办法。我以以下方式初始化了csv文件:

pandas_object = DataFrame(read_csv('/Path/to/csv/file', parse_dates=True, index_col = [2,0,1] ))
其中:

index_col = [2,0,1]
表示[年、月、日]的列


现在唯一的问题是,现在我有三个新的索引列,一个表示年,一个表示月,另一个表示日

这里有一个使用的替代方案。对于较小的数据帧,它似乎要快一点,对于较大的数据帧,它要快得多:

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]
将numpy导入为np
作为pd进口熊猫
数据帧({'M':[1,2,3,4],'D':[6,7,8,9],'Y':[1990199119921993]})
#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='将数据帧转换为字符串以便于字符串连接:

df=df.astype(str)
然后转换为日期时间,指定格式:

df.index=pd.to_datetime(df.Y+df.M+df.D,format="%Y%m%d")

它将替换索引,而不是创建新列。

让我们假设您有一个字典
foo
,每列日期都是并行的。如果是这样,下面是您的一行:

>>> from datetime import datetime
>>> foo = {"M": [1,2,3], "D":[30,30,21], "Y":[1980,1981,1982]}
>>>
>>> df = pd.DataFrame({"Datetime": [datetime(y,m,d) for y,m,d in zip(foo["Y"],foo["M"],foo["D"])]})
真正的勇气在于这一点:

>>> [datetime(y,m,d) for y,m,d in zip(foo["Y"],foo["M"],foo["D"])]
[datetime.datetime(1980, 1, 30, 0, 0), datetime.datetime(1981, 2, 28, 0, 0), datetime.datetime(1982, 3, 21, 0, 0)]
这就是
zip
的目的。它将并行列表转换为元组。然后通过列表理解将元组解包(y、m、d的
,在
位),然后输入到
日期时间
对象构造函数中


pandas
似乎对datetime对象很满意。

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

  • 列的名称必须是
    小时
    分钟
  • 最小列为
样本:

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]
另一种解决方案是转换为
字典

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]

更好的方法如下:

import pandas as pd

import datetime

dataset = pd.read_csv('dataset.csv')

date=dataset.apply(lambda x: datetime.date(int(x['Yr']), x['Mo'], x['Dy']),axis=1)

date = pd.to_datetime(date)

dataset = dataset.drop(columns=['Yr', 'Mo', 'Dy'])

dataset.insert(0, 'Date', date)

dataset.head()


谢谢,它成功了,你能解释一下*10000和*100的用途吗?没关系,目的是将2011,5,3转换成易于阅读的20110503。谢谢!!是的-这实际上是最快的方法,因为它们是矢量化的数字运算,转换为日期时间不会通过字符串进行往返有兴趣看看你是否能从
pd.to_datetime(dict(year=df.Y,month=df.M,day=df.D))
@holdenweb:根据
%timeit
,它们大致相同-数字版本可能比我使用的数据集快5-10%。我将使用dict版本,因为它更可读。尝试
解析日期=[[2,0,1]]
(请注意双括号。请看一下
read_csv
上的doctstring作为一个例子。我认为这或至少这一功能对熊猫来说是一个很好的增强。我们应该只找到一个API。是的,必须做
*10000
-1970
之类的事情是愚蠢的。我们肯定能够结合标准时间类型更简单。(如果有更好的方法,但我们都不知道,那么至少有一个文档错误。)请在代码中添加一些描述或注释。甚至(稍微)比建议的更快,因为我们甚至放弃了最小算术,谢谢jezrael!撇开性能讨论不谈,我发现转换到
dict
是最容易的。
>>> [datetime(y,m,d) for y,m,d in zip(foo["Y"],foo["M"],foo["D"])]
[datetime.datetime(1980, 1, 30, 0, 0), datetime.datetime(1981, 2, 28, 0, 0), datetime.datetime(1982, 3, 21, 0, 0)]
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]
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]
 [pd.to_datetime(str(a)+str(b)+str(c),
                 format='%m%d%Y'
                ) for a,b,c in zip(df.M, df.D, df.Y)]
import pandas as pd

import datetime

dataset = pd.read_csv('dataset.csv')

date=dataset.apply(lambda x: datetime.date(int(x['Yr']), x['Mo'], x['Dy']),axis=1)

date = pd.to_datetime(date)

dataset = dataset.drop(columns=['Yr', 'Mo', 'Dy'])

dataset.insert(0, 'Date', date)

dataset.head()