Порядок баз данных в Python - PullRequest
0 голосов
/ 09 июля 2011

У меня есть база данных, которая выглядит примерно так:

# user1, user2, action, days since 01/03/2010, week number, age1, age2, gen1, gen2
['1181206', '3560076', '2', 0, 0, '46', '45', 'M', 'F']
['1291903', '3675534', '2', 0, 0, '32', '30', 'M', 'F']
['3723809', '3686568', '1', 7, 1, '29', '26', 'M', 'F']
['3440145', '3258134', '1', 14, 2, '42', '42', 'M', 'F']
['3720125', '3147358', '1', 15, 2, '50', '51', 'F', 'M']
['2568920', '3753709', '1', 23, 3, '46', '43', 'M', 'F']
['3759313', '3541126', '1', 30, 4, '43', '42', 'M', 'F']
['3372869', '3409372', '1', 37, 5, '44', '45', 'F', 'M']
['2580655', '3816967', '1', 47, 6, '54', '48', 'M', 'F']
['3784183', '1978056', '1', 51, 7, '61', '50', 'M', 'F']
['4462684', '4406304', '1', 59, 8, '52', '51', 'F', 'M']
['3649081', '4524487', '1', 72, 10, '49', '47', 'M', 'F']
['4627173', '4537773', '3', 95, 13, '30', '37', 'F', 'M']
['4697735', '3144685', '1', 106, 15, '28', '29', 'F', 'M']
['3643353', '4740556', '1', 125, 17, '24', '29', 'F', 'M']
...

Есть около 5 миллионов строк. Каждая строка представляет деятельность. user1 выполняет действие над user2.

Мне нужно как-то заказать его, чтобы упростить задачу для каждого пользователя, и, в конце концов, я хочу знать:

  • Время в днях между первым и последним действиями пользователя.
  • Количество пользователей, например, 10-15 дней между первым и последним действием.

Я попытался отсортировать его так, чтобы каждое действие пользователя было сгруппировано, но это заняло бы слишком много времени на моей машине! (Около 3 дней) Хотя быстрый способ группировки активности каждого пользователя был бы хорош.

Я подумываю о создании класса Users (), каждый пользователь которого является объектом в классе с атрибутами: возраст, пол и активность.

Тогда говорят:

 for each line in database:
    if user doing the action is an object in the class:
        invoke a method which adds this activity to their activity attribute
    else:
        invoke a method which creates a new user object and add this to their 
activity.

Я не совсем уверен, как это сделать, есть ли метод, который может создавать новые объекты?

Затем каким-то образом перебирая все объекты в классе, определяя количество дней между их первым и последним действием.

Я знаю, что есть довольно много частей, поэтому помощь с любой из них очень ценится.

Ответы [ 2 ]

1 голос
/ 09 июля 2011

Вы можете использовать базу данных (sqlite будет проще всего) с Django Models :

class MyUser(models.Model):
    age = models.PositiveIntegerField()
    is_male = models.BooleanField()

class Activity(models.Model):
    user1 = models.ForeignKey(MyUser)
    user2 = models.ForeignKey(MyUser)
    activity_type = models.PositiveIntegerField()
    #timestamp = models.DateTimeField() # better
    days_since =  models.PositiveIntegerField()

Теперь переберите ваш текст:

for line in f:
    user1, _ = MyUser.objects.get_or_create(id=int(line[0]), age=int(line[5]), is_male=line[7]=='M')
    user2, _ = MyUser.objects.get_or_create(id=int(line[1]), age=int(line[6]), is_male=line[8]=='M')
    Activity.objects.create(user1=user1, user2=user2, activity_type=int(line[2]),  days_since=int(line[3]))

Ваша БДготов.Чтобы ответить на ваш первый вопрос, используйте:

MyUser.objects.annotate(max_days=Max('activities_from__days_since'), min_days=Min('activities_from__days_since'))
1 голос
/ 09 июля 2011

Довольно наивный подход: вашей структурой 'Users' может быть словарь (http://docs.python.org/tutorial/datastructures.html#dictionaries) активности пользователя, где ключом может быть имя пользователя, а значение в словаре будет структурой со старейшим и последняя активность.

Затем вы просматриваете список действий, и каждая строка либо:

  • новый пользователь (вы добавляете объект в словарь и начинаете самую раннюю и последнюю дату активности с даты активности текущей строки).

  • существующий пользователь (вы обнаружите активность этого пользователя в словаре и соответственно обновите самые старые / самые последние даты активности)

В конце вы получите активность всех пользователей. Теперь база данных будет расти так же, как количество пользователей в вашей базе данных; и время обработки будет занимать время, пропорциональное количеству строк. Это может вызвать проблемы:

  • чтение каждой строки базы данных может потребовать некоторой буферизации, чтобы избежать загрузки ее в память
  • словарь может быть слишком большим, чтобы поместиться в памяти, если у вас действительно много пользователей

Но и то, и другое зависит от базы данных и системы, которую вы используете.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...