Як павысіць прадукцыйнасць гэтага сцэнара?

З дапамогай пітона супольнасці я пачаў вывучаць Python апрацоўваць каля 500 мільёнаў (40G) дадзеных і напісаў наступны сцэнар.

Input File Format -

Studentid,Subject,DateTime,Grade
001,Biology,Mon Apr 25 19:32:00 PDT 2013,B
001,Literature,Wed Apr 10 15:31:00 PST 2013,B
001,Math,Mon Apr 22 01:32:00 PDT 2013,A
002,Biology,Mon Apr 25 19:32:00 PDT 2013,A
002,Math,Mon Apr 22 16:31:14 PDT 2013,C
002,Math,Wed Apr 10 15:31:00 PST 2013,C
003,Biology,Mon Apr 22 13:31:00 PDT 2013,A
003,Irdu,Wed Apr 10 15:31:00 PST 2013,A

<�Моцны> Выснова справаздачы

003,Irdu;Wed Apr 10 15:31:00 PST 2013;A#Biology;Mon Apr 22 13:31:00 PDT 2013;A
002,Math;Wed Apr 10 15:31:00 PST 2013;C#Math;Mon Apr 22 16:31:14 PDT 2013;C#Biology;Mon Apr 25 19:32:00 PDT 2013;A
001,Literature;Wed Apr 10 15:31:00 PST 2013;B#Math;Mon Apr 22 01:32:00 PDT 2013;A#Biology;Mon Apr 25 19:32:00 PDT 2013;B

Python Script

import csv
import time
import operator
import sys, getopt
import os

from collections import defaultdict
from datetime import datetime
from operator import itemgetter

start = time.time()
def elapsed():
    return time.time() - start

def date_key(row):
  try:
    formatRow = row[1].replace('PDT ','')
    formatRow = formatRow.replace('PST ','')
    return datetime.strptime(formatRow, "%a %b %d %X %Y")
  except Exception, e:
     print ("Error in sorting the date: %s \nRow : %s" % (e, row))
     pass

def processRecords(accountsData, fileName):
  for v in accountsData.itervalues():
    try:
      v.sort(key=date_key)
    except Exception, e:
      pass

  with open(fileName, 'a') as writer:
    for pid,v in accountsData.iteritems():
      csv = '#'.join([';'.join(t) for t in v])
      writer.write("%s,%s\n" % (pid, csv))

def main(argv):
  inputFile = ''
  outputFile = ''
  batchsize = 20000000
  try:
    opts, args = getopt.getopt(argv,"hi:o:b:",["ifile=","ofile=","bsize="])
  except getopt.GetoptError:
    print 'ReportToFileBatches.py -i <inputfile> -o  -b[default=20000000]'
    sys.exit(2)
  for opt, arg in opts:
    if opt == '-h':
      print 'ReportToFileBatches.py -i <inputfile> -o  -b[default=20000000]'
      sys.exit()
    elif opt in ("-i", "--ifile"):
      inputFile = arg
    elif opt in ("-o", "--ofile"):
      outputFile = arg
    elif opt in ("-b", "--bsize"):
      batchsize = int(arg)

  if not (os.path.isfile(inputFile)):
    print ("\nError : File - %s does not exist." % (inputFile)) 
    sys.exit(2)

  #print "Batch Size %s " % batchsize
  linenumb = 0  
  with open(inputFile,'r') as data:
    accounts = defaultdict(list)

    for line in data:
      linenumb = linenumb + 1
      line = line.rstrip('\r\n')
      try:
        sid, subject, datetime, grade = line.split(',')
        accounts[sid].append((subject, datetime, grade))

        if (linenumb == batchsize):
          linenumb = 0
          processRecords(accounts, outputFile)
          accounts = defaultdict(list)
        else: continue
      except Exception, e:
        print ("Error : %s \nRow : %s" % (e, line))  

  if(linenumb > 0):
    processRecords(accounts, outputFile)

  print("Total time taken - %.3fs" % elapsed())

if __name__ == "__main__":
   main(sys.argv[1:])

Вы можаце ўбачыць выхадны файл (справаздачу) упарадкаваны па даце, а таксама канкатэнацыі палёў. Я праводжу больш часу на сартаванне слупка DATETIME (можа быць). Я пачатковец у Python. Я вельмі ўдзячны за любую дапамогу ў паляпшэнні майго сцэнара, каб скараціць час апрацоўкі. Спадзяюся, што я сэнс.

FYI: Я пераканаўшыся, што ўваходны файл адсартаваны па studentid і апрацоўкі ў пакетным рэжыме.

1
Я мяркую, што вы карыстаецеся модуль профілю , каб знайсці скрыпты «гарачыя кропкі».
дададзена аўтар martineau, крыніца
Прафіляванне не так ужо цяжка. См Як можна прафіляванага сцэнар Python? .
дададзена аўтар martineau, крыніца
Прафіляванне не так ужо цяжка. См Як можна прафіляванага сцэнар Python? .
дададзена аўтар martineau, крыніца
Я павінен ісці з martineu на гэтым, прафіляванне толькі добры шлях наперад тут ... ваш код выглядае ўжо «прарочы» і выкарыстоўвае шмат трукаў, я прапанаваў бы. Калі вы проста занепакоеныя з атрыманнем паскарэння (а не з рэгулявальным кодам), вы таксама можаце паспрабаваць для хуткай выгады з чымсьці накшталт інтэрпрэтатара PyPy, але гэта ніколі не ўпэўнены, рэчы. Калі ласка, пост назад з вынікамі профілю, калі вам усё яшчэ трэба больш саветаў. Ура!
дададзена аўтар David, крыніца
Дзякуй. Паспрабую профилировщика. Я ўпэўнены, што гэта свайго роду, дзе я пераўтварыць радок даты ў звычайны DateTime
дададзена аўтар Think, крыніца
Дзякуй. Паспрабую профилировщика. Я ўпэўнены, што гэта свайго роду, дзе я пераўтварыць радок даты ў звычайны DateTime
дададзена аўтар Think, крыніца

6 адказы

Я нават не магу сабе ўявіць, жадаючы зрабіць гэта з любой сумай прафілявання або аптымізацыі Algorythm.

Гэта мяне дзівіць як праблема базы дадзеных.

  1. загрузіць дадзеныя ў да базы дадзеных (SQLite пастаўляецца з пітонам)
  2. дадаць індэкс даты
  3. дамп выхад

пітон мова клей, каб зрабіць фарматаванне і аналіз. Не мова згарнуць сваё ўласнае кіраванне 40G дадзеных.

1
дададзена

Я нават не магу сабе ўявіць, жадаючы зрабіць гэта з любой сумай прафілявання або аптымізацыі Algorythm.

Гэта мяне дзівіць як праблема базы дадзеных.

  1. загрузіць дадзеныя ў да базы дадзеных (SQLite пастаўляецца з пітонам)
  2. дадаць індэкс даты
  3. дамп выхад

пітон мова клей, каб зрабіць фарматаванне і аналіз. Не мова згарнуць сваё ўласнае кіраванне 40G дадзеных.

1
дададзена

Я нават не магу сабе ўявіць, жадаючы зрабіць гэта з любой сумай прафілявання або аптымізацыі Algorythm.

Гэта мяне дзівіць як праблема базы дадзеных.

  1. загрузіць дадзеныя ў да базы дадзеных (SQLite пастаўляецца з пітонам)
  2. дадаць індэкс даты
  3. дамп выхад

пітон мова клей, каб зрабіць фарматаванне і аналіз. Не мова згарнуць сваё ўласнае кіраванне 40G дадзеных.

1
дададзена

Я думаю, што лепшае, што вы можаце зрабіць, гэта класіфікуюць роду . Гэта працуе, калі вы ведаеце, межы і распаўсюджванне вашых дадзеных па часе, гэта значыць аб самых вялікіх і малых часоў. Сукно працы шляхам падзелу дадзеных у дыскрэтныя палічках. Напрыклад, калі дадзеныя размеркаваны каля месяца, то вы можаце мець масіў, дзе кожны індэкс ўяўляе сабой масіў, які ўяўляе 1 гадзіна кожны дзень гэтага месяца. Ідзе спіс, размяшчаючы свае дадзеныя ў гэты масіў. Пры размяшчэнні дадзеных у масіве, то вы можаце адсартаваць яго ў гэтым подсписка.

Гэты алгарытм вельмі эфектыўны, калі вы выбіраеце палічкі правільна. Напрыклад, калі ўсе вашы дадзеныя былі ў той жа дзень, і ваш голуб адтуліну было днём, то гэты алгарытм не выконвае ці не лепш, чым у вас. Яшчэ адна заўвага, што вы не калодкі павінны быць раўнамерна распаўсюджвацца. Калі амаль усе вашыя дадзеныя ў тую самую хвіліну ў розныя дні, а затым дадаць меншыя часовыя крокі ў тую гадзіну і больш буйныя для адпачынку.

Counting sort is another option (also has a better runtime), but since your file is so big I think you might run into memory issues or lag from constant disk writes. Worth looking into but be careful with those delays.

EDIT: Проста зразумеў, што ваш файл 40г вялікім, так што на рахунак для гэтага пытання памяці, замест масіва масіваў, вы маглі б мець шэраг файлаў з вядомымі імёнамі, якія ўтрымліваюць вашы сукно спісы.

0
дададзена

Я думаю, што лепшае, што вы можаце зрабіць, гэта класіфікуюць роду . Гэта працуе, калі вы ведаеце, межы і распаўсюджванне вашых дадзеных па часе, гэта значыць аб самых вялікіх і малых часоў. Сукно працы шляхам падзелу дадзеных у дыскрэтныя палічках. Напрыклад, калі дадзеныя размеркаваны каля месяца, то вы можаце мець масіў, дзе кожны індэкс ўяўляе сабой масіў, які ўяўляе 1 гадзіна кожны дзень гэтага месяца. Ідзе спіс, размяшчаючы свае дадзеныя ў гэты масіў. Пры размяшчэнні дадзеных у масіве, то вы можаце адсартаваць яго ў гэтым подсписка.

Гэты алгарытм вельмі эфектыўны, калі вы выбіраеце палічкі правільна. Напрыклад, калі ўсе вашы дадзеныя былі ў той жа дзень, і ваш голуб адтуліну было днём, то гэты алгарытм не выконвае ці не лепш, чым у вас. Яшчэ адна заўвага, што вы не калодкі павінны быць раўнамерна распаўсюджвацца. Калі амаль усе вашыя дадзеныя ў тую самую хвіліну ў розныя дні, а затым дадаць меншыя часовыя крокі ў тую гадзіну і больш буйныя для адпачынку.

Counting sort is another option (also has a better runtime), but since your file is so big I think you might run into memory issues or lag from constant disk writes. Worth looking into but be careful with those delays.

EDIT: Проста зразумеў, што ваш файл 40г вялікім, так што на рахунак для гэтага пытання памяці, замест масіва масіваў, вы маглі б мець шэраг файлаў з вядомымі імёнамі, якія ўтрымліваюць вашы сукно спісы.

0
дададзена

Я думаю, што лепшае, што вы можаце зрабіць, гэта класіфікуюць роду . Гэта працуе, калі вы ведаеце, межы і распаўсюджванне вашых дадзеных па часе, гэта значыць аб самых вялікіх і малых часоў. Сукно працы шляхам падзелу дадзеных у дыскрэтныя палічках. Напрыклад, калі дадзеныя размеркаваны каля месяца, то вы можаце мець масіў, дзе кожны індэкс ўяўляе сабой масіў, які ўяўляе 1 гадзіна кожны дзень гэтага месяца. Ідзе спіс, размяшчаючы свае дадзеныя ў гэты масіў. Пры размяшчэнні дадзеных у масіве, то вы можаце адсартаваць яго ў гэтым подсписка.

Гэты алгарытм вельмі эфектыўны, калі вы выбіраеце палічкі правільна. Напрыклад, калі ўсе вашы дадзеныя былі ў той жа дзень, і ваш голуб адтуліну было днём, то гэты алгарытм не выконвае ці не лепш, чым у вас. Яшчэ адна заўвага, што вы не калодкі павінны быць раўнамерна распаўсюджвацца. Калі амаль усе вашыя дадзеныя ў тую самую хвіліну ў розныя дні, а затым дадаць меншыя часовыя крокі ў тую гадзіну і больш буйныя для адпачынку.

Counting sort is another option (also has a better runtime), but since your file is so big I think you might run into memory issues or lag from constant disk writes. Worth looking into but be careful with those delays.

EDIT: Проста зразумеў, што ваш файл 40г вялікім, так што на рахунак для гэтага пытання памяці, замест масіва масіваў, вы маглі б мець шэраг файлаў з вядомымі імёнамі, якія ўтрымліваюць вашы сукно спісы.

0
дададзена