Оптимизация чтения из файла .gz и использование процессора python

Пример входного файла:

83,REGISTER,0,10.166.224.34,1518814163,[sip:[email protected]],sip:[email protected],3727925550,0600,NULL,NULL                                                                                             
83,INVITE,0,10.166.224.34,1518814163,[sip:[email protected]],sip:[email protected],3727925550,0600,NULL,NULL
83,INVITE,0,10.166.224.34,1518814163,[sip:[email protected]],sip:[email protected],3727925550,0600,NULL,NULL
83,REGISTER,0,10.166.224.34,1518814163,[sip:[email protected]],sip:[email protected],3727925550,0600,NULL,NULL
83,REGISTER,0,10.166.224.34,1518814163,[sip:[email protected]],sip:[email protected],3727925550,0600,NULL,NULL

Пример выходного файла:

1202677 REGISTER,INVITE
1202687 INVITE,REGISTER
1202678 REGISTER

Пример кода:

filesList=glob.glob("%s/*.gz" %(sys.argv[1]))

for file in filesList:
    try:
        fp = gzip.open(file, 'rb')
        f=fp.readlines()
        fp.close()
        for line in f:
            line = line.split(',')
            if line[0] == '83':
                str=line[5].split("[sip:")
                if len(str) > 1:
                    str=str[1].split("@")
                if dict.has_key(str[0].strip()):
                    dict[str[0].strip()] = dict.get(str[0].strip())+','+line[1]
                else:
                    dict[str[0].strip()] = line[1]
    except:
        print "Unexpected Error: ", sys.exc_info()[0]

try:
    with open(sys.argv[2],'w') as s:
        for num in dict:
            print >> s, num,dict[num]
except:
    print "Unexpected error:", sys.exc_info()[0]

Когда я запускаю приведенный выше скрипт с загрузкой 2,1 ГБ (430 файлов), его выполнение занимает около 13 минут, а загрузка ЦП составляет около 100%.

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                              
12586 root      20   0  156m 134m 1808 R 99.8  0.2   0:40.17 script

Пожалуйста, дайте мне знать, как я могу оптимизировать приведенный выше код, чтобы сократить время выполнения. Спасибо


person van neilsen    schedule 05.03.2018    source источник
comment
python 3.x или 2.7 - мясо или рыба? ваш код НЕ будет работать в 3.x   -  person Patrick Artner    schedule 05.03.2018
comment
Кроме того, SO любит неработающий код, улучшения кода лучше подходят для codereview.stackexchange.com   -  person Patrick Artner    schedule 05.03.2018
comment
Почему бы не использовать Панды?   -  person Abdulrahman Bres    schedule 05.03.2018
comment
@ ПатрикАртнер Python 2.6.2   -  person van neilsen    schedule 05.03.2018
comment
@Abdo Я никогда не использовал панд. Так что не знаю, как использовать   -  person van neilsen    schedule 05.03.2018
comment
Это намного проще, чем писать собственный код, и быстрее stackoverflow.com/questions/39263929/   -  person Abdulrahman Bres    schedule 05.03.2018


Ответы (1)


Попробуйте pandas. Если это все еще слишком медленно, есть инструменты, например. dask.dataframe, это может сделать его более эффективным.

df = pd.concat([pd.read_csv(f, header=None, usecols=[1, 5]) for f in files])
df[5] = df[5].str.split(':|@').apply(lambda x: x[1])
result = df.groupby(5)[1].apply(list)

# 5
# 1202677    [REGISTER, INVITE]
# 1202678            [REGISTER]
# 1202687    [INVITE, REGISTER]
# Name: 1, dtype: object
person jpp    schedule 05.03.2018