Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:读取CSV到列表的速度不比CSV到dict的速度快吗?_Python_Performance_List_Sorting_Dictionary - Fatal编程技术网

Python:读取CSV到列表的速度不比CSV到dict的速度快吗?

Python:读取CSV到列表的速度不比CSV到dict的速度快吗?,python,performance,list,sorting,dictionary,Python,Performance,List,Sorting,Dictionary,在寻找SAS排序的替代方案时,我决定尝试Python 2.6(两者都在同一台Unix服务器上)。在SAS中,对一个500行的窄表进行排序需要20分钟。 我将20%的表(100mln行)导出到CSV文件,如下所示: X|||465097434|912364420|0.00|0.00|0.00|0.00|1.00|01FEB2016|X|0|0 X|||465097434|912364420|0.00|0.00|0.00|0.00|0.00|02FEB2016|X|0|0 X|||465097434

在寻找SAS排序的替代方案时,我决定尝试Python 2.6(两者都在同一台Unix服务器上)。在SAS中,对一个500行的窄表进行排序需要20分钟。 我将20%的表(100mln行)导出到CSV文件,如下所示:

X|||465097434|912364420|0.00|0.00|0.00|0.00|1.00|01FEB2016|X|0|0
X|||465097434|912364420|0.00|0.00|0.00|0.00|0.00|02FEB2016|X|0|0
X|||465097434|912364420|0.00|0.00|0.00|0.00|2.00|03FEB2016|X|0|0
X|||465097434|912364421|0.00|0.00|0.00|0.00|3.00|04FEB2016|X|0|0
X|||465097434|912364421|0.00|0.00|0.00|0.00|6.00|05FEB2016|X|0|0
X|||965097411|912364455|0.00|0.00|0.00|0.00|4.00|04FEB2016|X|0|0
X|||965097411|912364455|0.00|0.00|0.00|0.00|1.00|05FEB2016|X|0|0
目标是按第5列和第11列对其进行排序。 首先,我用代码检查python读取文件的速度:

from __future__ import print_function
import csv
import time
linesRead=0
with open ('/path/to/file/CSV_FILE.csv','r') as dailyFile:
    allLines=csv.DictReader(dailyFile, delimiter='|')
    startTime=time.time()
    for row in allLines:
        linesRead += 1
        if (linesRead) % 1000000 == 0:
            print(linesRead, ": ", time.time()-startTime, " sec.")
            startTime=time.time()
结果是读取每个mln行需要6秒钟

1000000 :  6.6301009655  sec.
2000000 :  6.33900094032  sec.
3000000 :  6.26246404648  sec.
4000000 :  6.56919789314  sec.
5000000 :  6.17433309555  sec.
...
98000000 :  6.61627292633  sec.
99000000 :  7.14683485031  sec.
100000000 :  7.08069109917  sec.
所以我扩展了代码,将其加载到dictionary(key=column 5(account identifier)),value是这个帐户的列表(行)。 在这一点上,我意识到,当字典不断增长时,将列表加载到字典的速度会变慢(这很符合逻辑,因为需要检查的键越来越多):

时间是:

1000000, ': ', 8.9685721397399902, ' sec.')
(2000000, ': ', 10.344831943511963, ' sec.')
(3000000, ': ', 11.637137889862061, ' sec.')
(4000000, ': ', 13.024128913879395, ' sec.')
(5000000, ': ', 13.508150815963745, ' sec.')
(6000000, ': ', 14.94166088104248, ' sec.')
(7000000, ': ', 16.307464122772217, ' sec.')
(8000000, ': ', 17.130259990692139, ' sec.')
(9000000, ': ', 17.54616379737854, ' sec.')
(10000000, ': ', 20.254321813583374, ' sec.')
...
(39000000, ': ', 55.350741863250732, ' sec.')
(40000000, ': ', 56.762171983718872, ' sec.')
(41000000, ': ', 57.876702070236206, ' sec.')
(42000000, ': ', 54.548398017883301, ' sec.')
(43000000, ': ', 60.040227890014648, ' sec.')
这意味着没有机会在合理的时间内加载500mln行(5亿行中的最后一百万行将加载600秒)。 我的猜测是,每次迭代最慢的部分是检查字典中是否存在键:

if accountID in myDictionary:
因此,我将dictionary改为list,希望简单的追加会更快:

with open ('/path/to/file/CSV_FILE.csv','r') as dailyFile:
    allLines=csv.DictReader(dailyFile, delimiter='|')
    startTime=time.time()
    for row in allLines:
        linesRead += 1
        myList.append([row['account_id'].strip('\''), row['date'].strip('\''), row['balance1'], row['balance2'], row['balance3']])
        if (linesRead) % 1000000 == 0:
            print(linesRead, ": ", time.time()-startTime, " sec.")
            startTime=time.time()
不幸的是,性能根本没有提高:

1000000 :  9.15476489067  sec.
2000000 :  10.3512279987  sec.
3000000 :  12.2600080967  sec.
4000000 :  13.5473120213  sec.
5000000 :  14.8431830406  sec.
6000000 :  16.5556428432  sec.
7000000 :  17.6754620075  sec.
8000000 :  19.1299819946  sec.
9000000 :  19.7615978718  sec.
10000000 :  22.5903761387  sec.
加载列表的速度不应该比在条目处使用键检查加载字典快得多吗?

我是否滥用python来处理此类数据? 为了进行比较,我使用unix排序命令对文件进行排序:

$ date ; sort  -t'|' -k5,9 CSV_FILE.csv > delete.txt; date;
Sun Jul 23 18:46:16 CEST 2017
Sun Jul 23 19:06:53 CEST 2017

完成这项工作花了20分钟。在python中,我无法将数据加载到内存中。

我建议使用
pandas
,因为它应该更快。这将是读取
csv
文件的代码:

import pandas as pd
df = pd.read_csv('/path/to/file/CSV_FILE.csv', sep='|')
要对其进行排序,您可以使用:

df.sort_values([4, 10], ascending=[True,True], inplace=True)

注意:第一个列表是列名,其他参数是不言自明的。

Linux
sort
对于字典排序来说非常快。我不希望你能更快,除非使用更强大的硬件。实际上,
SAS
sort在同一时间内做了5倍长的数据集。同样大小(100mln)的数据集
SAS
在不到2分钟的时间内进行排序。实际上
pandas
比csv&list快得多。我在WindowsPython3.5.3(Linux服务器上没有熊猫)上测试了67mln行,熊猫导入时间:55秒。熊猫排序时间:47秒。而csv.DictReader和加载列表或dict为每百万10秒。有趣的是,它是稳定的10秒/行数,不像最初在Linux和Python 2.6上那样慢。我发现
pandas
在加载许多小型(1000行)csv文件时比
csv.reader
慢2倍。把这个放在这里是为了任何想做类似事情的人。
df.sort_values([4, 10], ascending=[True,True], inplace=True)