哪个是从给定日期提取日,月和年的最快方法?

时间:2014-02-22 12:18:17

标签: python date datetime pandas

我将包含150,000行的csv文件读入pandas数据帧。此数据框有一个字段“日期”,日期格式为 yyyy-mm-dd 。我想从中提取月,日和年,并分别复制到数据框的列,'月','日'和'年'。对于几百条记录,以下两种方法都可以正常工作,但对于150,000条记录,这两种方法都需要花费很长的时间来执行。对于100,000多条记录,有更快的方法吗?

第一种方法:

df = pandas.read_csv(filename)
for i in xrange(len(df)): 
   df.loc[i,'Day'] = int(df.loc[i,'Date'].split('-')[2])

第二种方法:

df = pandas.read_csv(filename)
for i in xrange(len(df)):
   df.loc[i,'Day'] = datetime.strptime(df.loc[i,'Date'], '%Y-%m-%d').day

谢谢。

3 个答案:

答案 0 :(得分:30)

在0.15.0中,您将能够使用新的.dt访问器在语法上做到这一点。

In [36]: df = DataFrame(date_range('20000101',periods=150000,freq='H'),columns=['Date'])

In [37]: df.head(5)
Out[37]: 
                 Date
0 2000-01-01 00:00:00
1 2000-01-01 01:00:00
2 2000-01-01 02:00:00
3 2000-01-01 03:00:00
4 2000-01-01 04:00:00

[5 rows x 1 columns]

In [38]: %timeit f(df)
10 loops, best of 3: 22 ms per loop

In [39]: def f(df):
    df = df.copy()
    df['Year'] = DatetimeIndex(df['Date']).year
    df['Month'] = DatetimeIndex(df['Date']).month
    df['Day'] = DatetimeIndex(df['Date']).day
    return df
   ....: 

In [40]: f(df).head()
Out[40]: 
                 Date  Year  Month  Day
0 2000-01-01 00:00:00  2000      1    1
1 2000-01-01 01:00:00  2000      1    1
2 2000-01-01 02:00:00  2000      1    1
3 2000-01-01 03:00:00  2000      1    1
4 2000-01-01 04:00:00  2000      1    1

[5 rows x 4 columns]

从0.15.0开始(2014年9月底发布),现在可以使用新的.dt访问器进行以下操作:

df['Year'] = df['Date'].dt.year
df['Month'] = df['Date'].dt.month
df['Day'] = df['Date'].dt.day

答案 1 :(得分:1)

This is the cleanest answer I've found.

df = df.assign(**{t:getattr(df.data.dt,t) for t in nomtimes})

In [30]: df = pd.DataFrame({'data':pd.date_range(start, end)})

In [31]: df.head()
Out[31]:
        data
0 2011-01-01
1 2011-01-02
2 2011-01-03
3 2011-01-04
4 2011-01-05

nomtimes = ["year", "hour", "month", "dayofweek"] 
df = df.assign(**{t:getattr(df.data.dt,t) for t in nomtimes})

In [33]: df.head()
Out[33]:
        data  dayofweek  hour  month  year
0 2011-01-01          5     0      1  2011
1 2011-01-02          6     0      1  2011
2 2011-01-03          0     0      1  2011
3 2011-01-04          1     0      1  2011
4 2011-01-05          2     0      1  2011

答案 2 :(得分:0)

我使用下面的代码,这对我很有用

df['Year']=[d.split('-')[0] for d in df.Date]
df['Month']=[d.split('-')[1] for d in df.Date]
df['Day']=[d.split('-')[2] for d in df.Date]

df.head(5)