سؤال

وأنا أعمل مع مصفوفة كبيرة (250x250x30 = 1،875،000 الخلايا)، وأحب طريقة لتعيين عدد التعسفي من الأعلام لكل خلية في هذه المصفوفة، بطريقة ما أن من السهل استخدام ومعقول الفضاء كفاءة .

وكانت خطتي الأصلية مجموعة 250x250x30 القائمة، حيث كان كل عنصر شيء من هذا القبيل: ["FLAG1","FLAG8","FLAG12"]. I ثم تغييره إلى تخزين الأعداد الصحيحة فقط بدلا من ذلك: [1,8,12]. يتم تعيين هذه الأعداد الصحيحة داخليا بواسطة وظائف جالبة / اضع لسلاسل العلم الأصلي. هذا يستخدم فقط 250MB مع 8 الأعلام في النقطة، التي على ما يرام من حيث الذاكرة.

وسؤالي هو: أنا في عداد المفقودين طريقة واضحة أخرى لتنظيم هذا النوع من البيانات

وبفضل جميع لاقتراحاتكم. انتهى بي الأمر المتداول بعض الاقتراحات في واحدة، للأسف يمكنني اختيار إجابة واحدة فقط، ويجب أن نعيش مع upvoting الآخرين:

وتحرير: إدارة مخاطر المؤسسات التعليمة البرمجية الأولي كان لي هنا (باستخدام مجموعات باعتبارها العنصر الأساسي من مجموعة نمباي 3D) يستخدم الكثير من الذاكرة. هذا الإصدار الجديد يستخدم حوالي 500MB عندما تمتلئ randint(0,2**1000).

import numpy

FLAG1=2**0
FLAG2=2**1
FLAG3=2**2
FLAG4=2**3

(x,y,z) = (250,250,30)

array = numpy.zeros((x,y,z), dtype=object)


def setFlag(location,flag):
    array[location] |= flag
def unsetFlag(location,flag):
    array[location] &= ~flag
هل كانت مفيدة؟

المحلول

وأود أن استخدام عموما نمباي مجموعة (ويفترض من [إينتس] قصيرة، 2 بايت لكل منهما، وبما انك قد تحتاج إلى أكثر من 256 قيم مميزة) - من شأنها أن تأخذ أقل من 4MB ل<2000000 خلايا

إذا لسبب ما لم أستطع تحمل التبعية نمباي (على سبيل المثال على محرك التطبيقات، والذي لا يعتمد نمباي)، فما استقاموا لكم فاستقيموا استخدام المكتبة القياسية <لأ href = "http://docs.python.org /library/array.html "يختلط =" نوفولو noreferrer "> وحدة مجموعة - انها لا تدعم سوى صفائف 1 الأبعاد، ولكن هذا مجرد كمساحة كفاءة كما نمباي للصفائف متجانسة كبيرة، وإجراءات جالبة / اضع لكم يذكر أن جيدا "خطي" 3 بنود الصفوف (tuple) وهذا مؤشر الطبيعي الخاص بك في مؤشر عدد صحيح واحد في مجموعة 1-D.

في عام، والنظر في نمباي (أو مجموعة) أي وقت لديك كبيرة متجانسة، وناقلات كثيفة أو مصفوفات أرقام - بيثون المدمج في القوائم والإسراف جدا من الفضاء في هذه الحالة استخدام (بسبب عمومية والذي كنت لا تستخدم ولست بحاجة هنا -!)، وتوفير الذاكرة تترجم بشكل غير مباشر لتوفير الوقت اللازم (التخزين المؤقت أفضل، ومستويات أقل من المراوغة، الخ، الخ)

نصائح أخرى

والحل الخاص بك على ما يرام إذا كان كل خلية واحدة وستكون لدينا علم. ولكن إذا كنت تعمل مع مجموعة بيانات متفرق حيث لا يوجد سوى الفرعي صغيرة من الخلايا الخاصة بك وسوف يكون الأعلام ما كنت تريد حقا هو القاموس. هل ترغب في إعداد dictonary ذلك المفتاح هو الصفوف (tuple) لموقع الخلية والقيمة هي قائمة الأعلام وكأنه لديك في الحل.

allFlags = {(1,1,1):[1,2,3], (250,250,30):[4,5,6]}

وهنا لدينا خلية 1،1،1 لها أعلام 1،2، و 3 والخلية 250،250،30 ديك أعلام 4،5 و 6

وتحرير- الثابتة الصفوف الأساسية، وذلك بفضل اندريه، وبناء القاموس.

ويمكنك تحديد بعض الثوابت مختلفة، قوة قيمتين على النحو التالي:

FLAG1 = 0x01
FLAG8 = 0x02
FLAG12 = 0x04
...

واستخدامها مع منطق منطقية لتخزين الأعلام في عدد صحيح واحد فقط، p.e:.

flags = FLAG1 | FLAG8

لمعرفة ما اذا كان ممكنا العلم، يمكنك استخدام المشغل &:

flag1_enabled = flags & FLAG1

إذا تم تمكين العلم، وهذا التعبير بإرجاع قيمة غير صفرية، التي سيتم تقييمها صحيح في أي عملية منطقية. إذا تم تعطيل العلم، فإن التعبير بإرجاع 0، وهذا هو تقييمها خطأ في العمليات المنطقية.

والنظر في استخدام نمط وزن الذبابة لتبادل خصائص الخلية:

http://en.wikipedia.org/wiki/Flyweight_pattern

BitSet هو ما تريد، لأنه يسمح لك لتخزين العديد من الأعلام في وقت واحد باستخدام فقط حجم عدد صحيح ثابت (نوع int)

وأخذ اقتراح روبي خطوة أخرى إلى الأمام ...

flags = set()
x, y, flag = 34, 201, 3
flags.add((x, y, flag)) # set flag 3 at position (34, 201)
if (3, 2, 1) in flags: # check if flag 1 is at position (3, 2)
    # do something
else:
    # do something else

ويمكنك أيضا إنشاء فئة المساعد.

class Flags(object):
    def __init__(self):
        self.data = set()
    def add(self, x, y, flag):
        self.data.add((x, y, flag))
    def remove(self, x, y, flag):
        self.data.remove((x, y, flag))
    def contains(self, x, y, flag):
        return (x, y, flag) in self.data

ويمكنك أيضا تنفيذ أساليب خاصة بايثون مثل __contains__ لجعله أسهل للعمل مع.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top