使用大熊猫组合日期和时间列

我有一个熊猫数据框,其中有以下几栏:

data = {'Date': ['01-06-2013', '02-06-2013', '02-06-2013', '02-06-2013', '02-06-2013', '03-06-2013', '03-06-2013', '03-06-2013', '03-06-2013', '04-06-2013'],
'Time': ['23:00:00', '01:00:00', '21:00:00', '22:00:00', '23:00:00', '01:00:00', '21:00:00', '22:00:00', '23:00:00', '01:00:00']}
df = pd.DataFrame(data)


Date      Time
0  01-06-2013  23:00:00
1  02-06-2013  01:00:00
2  02-06-2013  21:00:00
3  02-06-2013  22:00:00
4  02-06-2013  23:00:00
5  03-06-2013  01:00:00
6  03-06-2013  21:00:00
7  03-06-2013  22:00:00
8  03-06-2013  23:00:00
9  04-06-2013  01:00:00

如何组合数据[‘ Date’]和数据[‘ Time’]以得到以下内容?有没有一种使用 pd.to_datetime的方法?

Date
01-06-2013 23:00:00
02-06-2013 01:00:00
02-06-2013 21:00:00
02-06-2013 22:00:00
02-06-2013 23:00:00
03-06-2013 01:00:00
03-06-2013 21:00:00
03-06-2013 22:00:00
03-06-2013 23:00:00
04-06-2013 01:00:00
200895 次浏览

值得一提的是,您可能已经能够在 直接中读到这一点,例如,如果您使用 parse_dates=[['Date', 'Time']]使用 read_csv

假设这些仅仅是字符串,您可以简单地将它们添加到一起(使用空格) ,从而允许您使用 to_datetime,它不需要指定 format=参数即可工作

In [11]: df['Date'] + ' ' + df['Time']
Out[11]:
0    01-06-2013 23:00:00
1    02-06-2013 01:00:00
2    02-06-2013 21:00:00
3    02-06-2013 22:00:00
4    02-06-2013 23:00:00
5    03-06-2013 01:00:00
6    03-06-2013 21:00:00
7    03-06-2013 22:00:00
8    03-06-2013 23:00:00
9    04-06-2013 01:00:00
dtype: object


In [12]: pd.to_datetime(df['Date'] + ' ' + df['Time'])
Out[12]:
0   2013-01-06 23:00:00
1   2013-02-06 01:00:00
2   2013-02-06 21:00:00
3   2013-02-06 22:00:00
4   2013-02-06 23:00:00
5   2013-03-06 01:00:00
6   2013-03-06 21:00:00
7   2013-03-06 22:00:00
8   2013-03-06 23:00:00
9   2013-04-06 01:00:00
dtype: datetime64[ns]

或者,不使用 + ' ',但必须使用 format=参数。此外,熊猫善于推断格式转换为 datetime,但是,指定确切的格式是更快的。

pd.to_datetime(df['Date'] + df['Time'], format='%m-%d-%Y%H:%M:%S')

注意: 令人惊讶的是(对于我来说) ,这对于将 NaNs 转换为 NaT 很有用,但是值得担心的是转换(可能使用 raise参数)。

%%timeit

# sample dataframe with 10000000 rows using df from the OP
df = pd.concat([df for _ in range(1000000)]).reset_index(drop=True)


%%timeit
pd.to_datetime(df['Date'] + ' ' + df['Time'])
[result]:
1.73 s ± 10.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)


%%timeit
pd.to_datetime(df['Date'] + df['Time'], format='%m-%d-%Y%H:%M:%S')
[result]:
1.33 s ± 9.88 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

接受的答案适用于数据类型为 string的列。为了完整起见: 在搜索当列的数据类型为: date 和 time 时如何进行此操作时,我遇到了这个问题。

df.apply(lambda r : pd.datetime.combine(r['date_column_name'],r['time_column_name']),1)

我没有足够的声誉来评论 JKA.ne,所以:

我必须修改 JKA.ne 的台词才能正常工作:

df.apply(lambda r : pd.datetime.combine(r['date_column_name'],r['time_column_name']).time(),1)

这也许能帮到其他人。

此外,我还测试了一种不同的方法,使用 replace而不是 combine:

def combine_date_time(df, datecol, timecol):
return df.apply(lambda row: row[datecol].replace(
hour=row[timecol].hour,
minute=row[timecol].minute),
axis=1)

在 OP 的案例中是这样的:

combine_date_time(df, 'Date', 'Time')

我为一个相对较大的数据集(> 500.000行)计时了两种方法,它们都有相似的运行时,但使用 combine更快(replace为59秒,combine为50秒)。

您可以使用它将日期和时间合并到数据框的同一列中。

import pandas as pd
data_file = 'data.csv' #path of your file

阅读带合并列的.csv 文件日期 _ 时间:

data = pd.read_csv(data_file, parse_dates=[['Date', 'Time']])

您也可以使用此行来保留其他两列。

data.set_index(['Date', 'Time'], drop=False)

如果类型不同(datetimetimestampstr) ,则对列进行铸造,并使用 to_datetime:

df.loc[:,'Date'] = pd.to_datetime(df.Date.astype(str)+' '+df.Time.astype(str))

结果:

0   2013-01-06 23:00:00
1   2013-02-06 01:00:00
2   2013-02-06 21:00:00
3   2013-02-06 22:00:00
4   2013-02-06 23:00:00
5   2013-03-06 01:00:00
6   2013-03-06 21:00:00
7   2013-03-06 22:00:00
8   2013-03-06 23:00:00
9   2013-04-06 01:00:00

贝斯特,

答案是 实际上取决于列类型。在我的例子中,我有 datetimetimedelta

> df[['Date','Time']].dtypes
Date     datetime64[ns]
Time    timedelta64[ns]

如果是这种情况,那么您只需添加以下列:

> df['Date'] + df['Time']

还可以通过组合 to_datetimeto_timedelta(它们分别创建 datetimetimedeltea对象) ,在不使用字符串串联的情况下转换为 datetime。结合 pd.DataFrame.pop,您可以同时删除源系列:

df['DateTime'] = pd.to_datetime(df.pop('Date')) + pd.to_timedelta(df.pop('Time'))


print(df)


DateTime
0 2013-01-06 23:00:00
1 2013-02-06 01:00:00
2 2013-02-06 21:00:00
3 2013-02-06 22:00:00
4 2013-02-06 23:00:00
5 2013-03-06 01:00:00
6 2013-03-06 21:00:00
7 2013-03-06 22:00:00
8 2013-03-06 23:00:00
9 2013-04-06 01:00:00


print(df.dtypes)


DateTime    datetime64[ns]
dtype: object

首先确保拥有正确的数据类型:

df["Date"] = pd.to_datetime(df["Date"])
df["Time"] = pd.to_timedelta(df["Time"])

然后你很容易地把它们结合起来:

df["DateTime"] = df["Date"] + df["Time"]

使用 combine函数:

datetime.datetime.combine(date, time)

我的数据集有几天的1秒钟的分辨率数据,用这里建议的方法解析是非常慢的。相反,我用了:

dates = pandas.to_datetime(df.Date, cache=True)
times = pandas.to_timedelta(df.Time)
datetimes  = dates + times

请注意,使用 cache=True可以非常有效地解析日期,因为在我的文件中只有几个唯一的日期,而对于合并的日期和时间列则不是这样。

资料:

[ TICKER > ,< PER > ,< 日期 > ,< 时间 > ,< OPEN > ,< HIGH > ,< LOW > ,< CLOSE > ,< VOL > SPFB.RTS,1,20190103,100100,106580.000000,107260.000000,106570.000000,107230.000000,3726

密码:

data.columns = ['ticker', 'per', 'date', 'time', 'open', 'high', 'low', 'close', 'vol']
data.datetime = pd.to_datetime(data.date.astype(str) + ' ' + data.time.astype(str), format='%Y%m%d %H%M%S')

这里有一行,做到这一点。您只需在每一列中的两个字符串之间添加一个“”空格即可。

假设 df 是你的数据框,列是‘ Time’和‘ Date’,你的新列是 DateAndTime。

df['DateAndTime'] = df['Date'].str.cat(df['Time'],sep=" ")

如果还想处理诸如 datetime 对象之类的条目,可以这样做。您可以根据需要调整格式。

df['DateAndTime'] = pd.to_datetime(df['DateAndTime'], format="%m/%d/%Y %I:%M:%S %p")

干杯! 数据处理愉快。

我认为最好的解决方案是直接解析 read_csv(或其他 read _ function)中的日期。如何管理 date _ parser 中的两列并不明显,但下面是:

date_parser = lambda x,y: datetime.strptime(f"{x}T{y}", "%d-%m-%YT%H:%M:%S")
date = pd.read_csv('data.csv', parse_dates={'date': ['Date', 'Time']}, date_parser=date_parser)