读取csv时加快日期时间格式化

时间:2019-05-18 04:10:27

标签: python python-3.x pandas

我有一个csv文件,其中包含4条以上的记录。

我使用pd.read_csv('big_file.csv',dtype = object)导入

此文件有2列,其日期采用以下格式: 'yyyy-mm-ddThh:mm:ss.nsTZ'例如'2018-05-05T04:39:09.447Z'

我需要将它们转换为 'yyyy-mm-dd H:M:S'例如'2018-09-23 06:03:12'

我使用以下代码进行操作:

df['created'] = pd.to_datetime(arg=df.created).dt.strftime('%Y-%m-%d %H:%M:%S')
df['lastLogin'] = pd.to_datetime(arg=df.lastLogin).dt.strftime('%Y-%m-%d %H:%M:%S')
df['lastUpdated'] = pd.to_datetime(arg=df.lastUpdated).dt.strftime('%Y-%m-%d %H:%M:%S')
df['created'] = pd.to_datetime(arg=df.created)
df['lastLogin'] = pd.to_datetime(arg=df.lastLogin)
df['lastUpdated'] = pd.to_datetime(arg=df.lastUpdated)

此过程非常慢:

CPU times: user 1min 48s, sys: 1.19 s, total: 1min 49s
Wall time: 1min 49s

有没有办法加快速度?

2 个答案:

答案 0 :(得分:1)

由于您的时间戳遵循非标准格式,因此我建议在读取csv文件时将参数 parse_dates date_parser 与自定义解析器一起使用,例如:

parser = lambda date: pd.datetime.strptime(date, '%Y-%m-%dT%H:%M:%S.%Z')
df = pd.read_csv('big_file.csv', 
                 parse_dates=['created', 'lastLogin', 'lastUpdated'],
                 date_parser=parser)

来自pandas documentation

  

date_parser:函数,可选

     

用于将字符串列序列转换为日期时间实例数组的函数。默认使用dateutil.parser.parser进行转换。熊猫将尝试以三种不同的方式调用date_parser,如果发生异常,则前进到下一个:1)将一个或多个数组(由parse_dates定义)作为参数传递; 2)将parse_dates定义的列中的字符串值连接(逐行)到单个数组中并将其传递;和 3)使用一个或多个字符串(对应于parse_dates定义的列)作为参数,为每一行调用date_parser。

答案 1 :(得分:0)

根据评论,我了解到您不需要日期的含义,而只是想更改代表日期的字符串的美学外观。然后,您可以将数据简单地视为字符串。所以,我是这样做的。

#!/usr/bin/python3

import numpy as np
import sys

def gen_sample(numdata, outfname):
    yy=np.random.randint(1905, 2018, 2*numdata)
    mm=np.random.randint(   1,   13, 2*numdata)
    dd=np.random.randint(   1,   29, 2*numdata)
    hhh=np.random.randint(   0,   25, 2*numdata)
    mmm=np.random.randint(   0,   61, 2*numdata)
    sss=np.random.randint(   0,   61, 2*numdata)
    baboon=np.random.randint(   0, 1000, 2*numdata)
    with open(outfname, 'w') as outf:
        for jj in range(numdata):
            outf.write('%4.4i-%2.2i-%2.2iT%2.2i:%2.2i:%2.2i.%3.3iZ,%4.4i-%2.2i-%2.2iT%2.2i:%2.2i:%2.2i.%3.3iZ\n'
                       %(yy[2*jj],   mm[2*jj],   dd[2*jj],
                         hhh[2*jj],  mmm[2*jj],  sss[2*jj],  baboon[2*jj],
                         yy[2*jj+1], mm[2*jj+1], dd[2*jj+1],
                         hhh[2*jj+1], mmm[2*jj+1], sss[2*jj+1], baboon[2*jj+1]))


def convert(infname,outfname):

    data=np.loadtxt(infname, dtype=np.str, delimiter=',', ndmin=2)
    with open(outfname,'w') as outf:
        for jr in range(data.shape[0]):
            outf.write('%s %s,%s %s\n'%(
                data[jr,0][0:10],
                data[jr,0][11:19],
                data[jr,1][0:10],
                data[jr,1][11:19] ))


if __name__=='__main__':
    sample_fname= 'daa.csv'
    out_fname= 'daadaa.csv'
    if len(sys.argv)>1:
        numdata=int(sys.argv[1])
        gen_sample(numdata, sample_fname)
    else:
        convert(sample_fname, out_fname)

,我花了大约15秒的时间在计算机上读取4M * 2数据。请看这个

#!/bin/bash

for jj in 0 1 2
do
  echo "generating sample.."
  ./main.py 4000000
  echo "loading, converting, and writing.."
  echo "----"
  /usr/bin/time ./main.py 
  echo "----"
done

还有这个

$ ./run.sh 
generating sample..
loading, converting, and writing..
----
14.96user 0.94system 0:15.05elapsed 105%CPU (0avgtext+0avgdata 818724maxresident)k
8inputs+312504outputs (0major+315787minor)pagefaults 0swaps
----
generating sample..
loading, converting, and writing..
----
14.91user 0.93system 0:14.99elapsed 105%CPU (0avgtext+0avgdata 818848maxresident)k
16inputs+312504outputs (0major+315864minor)pagefaults 0swaps
----
generating sample..
loading, converting, and writing..
----
15.39user 0.95system 0:15.52elapsed 105%CPU (0avgtext+0avgdata 818736maxresident)k
8inputs+312504outputs (0major+315857minor)pagefaults 0swaps
----

输入文件就像

$ head daa.csv 
2016-10-05T08:07:03.214Z,1973-10-01T12:36:21.367Z
1961-08-24T02:08:57.436Z,1953-03-06T00:56:12.486Z
1986-09-07T17:15:60.322Z,1952-11-19T19:02:56.159Z
1939-08-17T05:13:19.659Z,1920-12-15T16:46:52.628Z
2004-11-09T02:29:25.905Z,1925-02-07T10:37:49.142Z
2011-12-12T10:46:38.583Z,1992-02-10T08:58:60.284Z
1968-01-23T05:05:05.151Z,1935-09-17T07:12:49.392Z
1916-04-05T18:55:35.281Z,1919-10-12T10:05:10.249Z
1970-10-04T21:45:16.751Z,1951-01-08T16:58:51.190Z
1910-01-19T22:12:04.088Z,2006-03-08T09:26:45.690Z

输出文件就像

$ head daadaa.csv 
2016-10-05 08:07:03,1973-10-01 12:36:21
1961-08-24 02:08:57,1953-03-06 00:56:12
1986-09-07 17:15:60,1952-11-19 19:02:56
1939-08-17 05:13:19,1920-12-15 16:46:52
2004-11-09 02:29:25,1925-02-07 10:37:49
2011-12-12 10:46:38,1992-02-10 08:58:60
1968-01-23 05:05:05,1935-09-17 07:12:49
1916-04-05 18:55:35,1919-10-12 10:05:10
1970-10-04 21:45:16,1951-01-08 16:58:51
1910-01-19 22:12:04,2006-03-08 09:26:45

如果您不需要将转换后的数据写回到文件中, 也许运行时间会更快。 您需要使该函数对自己的数据变型更健壮,但我希望这个想法能够兑现。