2012-06-11 1 views
0

Я работал над этим немного времени сейчас, пытаясь создать сторону базы данных распределения частот:Как эффективно обрабатывать db-запросы для вычисления freq dist?

from itertools import permutations 
import sqlite3 

def populate_character_probabilities(connection, table="freq_dist", alphabet='abcdefghijklmnopqrstuvwxyz'): 
    c = connection.cursor() 
    c.execute("DROP TABLE IF EXISTS tablename".replace('tablename', table)) 
    c.execute("create table tablename (char1 text, char2 text, freq integer);".replace("tablename", table))  
    char_freq_tuples = [x + (1,) for x in list(permutations(alphabet, 2)) + [(alpha, alpha) for alpha in alphabet + 'S' + 'E']] 
    c.executemany("insert into tablename values (?,?,?);".replace("tablename", table), char_freq_tuples) 
    connection.commit() 
    c.close() 

def populate_word_list(connection, table="word_list"): 
    cursor = connection.cursor() 
    cursor.execute("DROP TABLE IF EXISTS tablename".replace('tablename', table)) 
    cursor.execute("create table tablename (word text);".replace('tablename', table)) 
    cursor.executemany("insert into tablename values (?)".replace('tablename', table), [[u'nabisco'], [u'usa'], [u'sharp'], [u'rise']]) 
    connection.commit() 

def update_freq_dist(connection, word_list="word_list", freq_dist="freq_dist"): 
    cursor = connection.cursor() 
    subset = cursor.execute("select * from tablename;".replace("tablename", word_list)).fetchmany(5) 
    for elem in subset: # want to process e.g.: 5 at a time 
     elem = 'S' + elem[0] + 'E' # Start and end delimiters 
     for i in xrange(len(elem) - 1): 
      freq = cursor.execute("SELECT freq FROM tablename WHERE char1=? and char2=?;".replace("tablename", freq_dist), (elem[i], elem[i + 1])).fetchone() 
      cursor.execute("UPDATE tablename SET freq=? WHERE char1=? and char2=?;".replace("tablename", freq_dist), (freq + 1, elem[i], elem[i + 1])) 
    connection.commit() # seems inefficient having two queries here^ 
    cursor.close() 

if __name__ == '__main__': 
    connection = sqlite3.connect('array.db') 
    populate_word_list(connection) 
    populate_character_probabilities(connection) 
    update_freq_dist(connection) 
    cursor = connection.cursor() 
    print cursor.execute("SELECT * FROM freq_dist;").fetchmany(10) 

(Ничего себе, получил, что 180 линии кодового до 37 для теста-случая: D - Обратите внимание, что фактический список слово 29000000 не 4 !!!)

Я понял, что:

  • мне не нужно два запроса в update_freq_dist внутреннем цикле
  • Существует способ переборе элементов базы данных (строк), например .: 5, в то время

Однако я не уверен, как я могу решить ни проблему.

Можете ли вы придумать решение?

ответ

1

Вы просто хотите обновить частоту + 1?

UPDATE tablename 
SET freq = freq + 1 
WHERE char1=? and char2=?; 

Или, если вы обновляете из другой таблицы:

UPDATE tablename 
SET freq = t2.freq + 1 -- whatever your calc is 
FROM tablename t1 
JOIN othertable t2 
ON t1.other_id = t2.id 
WHERE t1.char1=? and t1.char2=? and t2.char1=? and t2.char2=? 

Что касается итерация 5, в то время - вы можете использовать limit and offset пункты, чтобы получить что-то близкое.

Смежные вопросы