Какова самая эффективная структура данных графика в Python? [закрытый]

Я столкнулся с этой проблемой, когда попытался сохранить модель Peewee в PostgreSQL JSONField.

После долгой работы, вот общее решение.

Ключ к моему решение проходит через исходный код Python и понимает, что документация по коду (описанная здесь здесь ) уже объясняет, как расширить существующий json.dumps для поддержки других типов данных.

Предположим, что вы иметь модель, которая содержит некоторые поля, которые не могут быть сериализованы для JSON, и модель, которая содержит поле JSON, первоначально выглядит следующим образом:

class SomeClass(Model):
    json_field = JSONField()

Просто определите пользовательский JSONEncoder, как это:

class CustomJsonEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, SomeTypeUnsupportedByJsonDumps):
            return < whatever value you want >
        return json.JSONEncoder.default(self, obj)

    @staticmethod
    def json_dumper(obj):
        return json.dumps(obj, cls=CustomJsonEncoder)

А затем просто используйте его в своем JSONField, как показано ниже:

class SomeClass(Model):
    json_field = JSONField(dumps=CustomJsonEncoder.json_dumper)

Ключом является метод default(self, obj) выше. Для каждой жалобы ... is not JSON serializable, которую вы получаете от Python, просто добавьте код для обработки типа unserializable-to-JSON (например, Enum или datetime)

Например, вот как я поддерживаю класс, наследующий от Enum:

class TransactionType(Enum):
   CURRENT = 1
   STACKED = 2

   def default(self, obj):
       if isinstance(obj, TransactionType):
           return obj.value
       return json.JSONEncoder.default(self, obj)

Наконец, с помощью кода, реализованного, как описано выше, вы можете просто преобразовать любые модели Peewee в объект JSON-seriazable, как показано ниже:

peewee_model = WhateverPeeweeModel()
new_model = SomeClass()
new_model.json_field = model_to_dict(peewee_model)

Хотя приведенный выше код был (несколько) специфичен для Peewee, но я думаю:

  1. Он применим к другим ORM (Django и т. д.) вообще
  2. . Кроме того, если вы понимаете, как работает json.dumps, это решение также работает с Python (без ORM) вообще

. Все вопросы, пожалуйста, публикуйте в разделе комментариев. Спасибо!

65
задан Dominique Fortin 22 March 2017 в 17:42
поделиться

5 ответов

Я сильно защитил бы Вас взгляд NetworkX. Это - проверенный в бою боевой конь и первый инструмент, которого большинство типов 'исследования' достигает для того, когда они должны сделать анализ основанных на сети данных. Я управлял графиками с 100 с тысяч краев без проблемы на ноутбуке. Его многофункциональное и очень простое в использовании. Вы будете фокусироваться больше на проблеме под рукой, а не деталях в конкретной реализации.

Пример ErdЕ‘s-RГ©nyi случайное поколение графика и анализ


"""
Create an G{n,m} random graph with n nodes and m edges
and report some properties.

This graph is sometimes called the Erd##[m~Qs-Rényi graph
but is different from G{n,p} or binomial_graph which is also
sometimes called the Erd##[m~Qs-Rényi graph.
"""
__author__ = """Aric Hagberg (hagberg@lanl.gov)"""
__credits__ = """"""
#    Copyright (C) 2004-2006 by 
#    Aric Hagberg 
#    Dan Schult 
#    Pieter Swart 
#    Distributed under the terms of the GNU Lesser General Public License
#    http://www.gnu.org/copyleft/lesser.html

from networkx import *
import sys

n=10 # 10 nodes
m=20 # 20 edges

G=gnm_random_graph(n,m)

# some properties
print "node degree clustering"
for v in nodes(G):
    print v,degree(G,v),clustering(G,v)

# print the adjacency list to terminal 
write_adjlist(G,sys.stdout)

Визуализация также проста:

enter image description here

[еще 119] визуализация: http://jonschull.blogspot.com/2008/08/graph-visualization.html

52
ответ дан Maxime R. 24 November 2019 в 15:31
поделиться

Как уже упомянуто, NetworkX очень хорош с другой опцией, являющейся igraph. Оба модуля будут иметь большинство (если не все) аналитическими инструментами, в которых Вы, вероятно, будете нуждаться, и обеими библиотеками обычно пользуются с большими сетями.

6
ответ дан Kai 24 November 2019 в 15:31
поделиться

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

Оценка по Вашему примеру, "Свойству", Вы были бы лучше из с подходом класса для заключительного уровня и реальных свойств? Или названия свойств изменяющийся много от узла до узла?

я сказал бы, что то, что "эффективный" означает, зависит от большого количества вещей, как:

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

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

словарь А мог бы быть простым в использовании, и предоставить Вам относительно однородно доступ, он будет, скорее всего, использовать больше памяти, чем, как Вы предполагаете, списки. Списки, однако, обычно имеют тенденцию содержать больше служебное при вставке данных в него если они не предварительно выделяют X узлов, в которых они будут снова использовать больше памяти.

Мое предложение, в целом, должно было бы просто использовать метод, который кажется самым естественным для Вас, и затем сделайте "стресс-тест" системы, добавив значительное количество данных к нему и посмотрите, становится ли это проблемой.

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

4
ответ дан angry person 24 November 2019 в 15:31
поделиться

Насколько я понимаю произвольный доступ находится в постоянное время и для dicts и для списков Python, различие - то, что можно только сделать произвольный доступ целочисленных индексов со списками. Я предполагаю, что Вам нужен к поиску узел его маркировкой, таким образом, Вы хотите dict dicts.

Однако на передней стороне производительности, загружаясь это в память не может быть проблема, но если Вы будете использовать слишком много, то Вы закончите тем, что подкачали к диску, который уничтожит производительность даже высокоэффективного dicts Python. Попытайтесь подавить использование памяти как можно больше. Кроме того, RAM является удивительно дешевой прямо сейчас; если Вы делаете такого рода вещь много, нет никакой причины не иметь по крайней мере 4 ГБ.

, Если Вы хотели бы совет относительно подавления использования памяти, дайте еще некоторую информацию о виде информации, которую Вы отслеживаете для каждого узла.

3
ответ дан Peter Burns 24 November 2019 в 15:31
поделиться

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

2
ответ дан Matthew Schinckel 24 November 2019 в 15:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: