سؤال

سؤال بيثون. أقوم بإنشاء مجموعة كبيرة من الكائنات ، والتي أحتاجها فقط لصنع عينة عشوائية صغيرة. في الواقع ، يستغرق إنشاء الكائنات المعنية بعض الوقت ، لذلك أتساءل عما إذا كان من الممكن تخطي تلك الكائنات التي لا تحتاج إلى توليدها وإنشاء تلك الكائنات التي تم أخذ عينات منها بشكل صريح.

بمعنى آخر ، لدي الآن

a = createHugeArray()
s = random.sample(a,len(a)*0.001)

وهو مضيعة إلى حد ما. أفضل أن يكون هناك شيء أكثر كسولًا

a = createArrayGenerator()
s = random.sample(a,len(a)*0.001)

لا أعرف ما إذا كان هذا يعمل. الوثائق الخاصة بـ Random.Sample ليست واضحة جدًا ، على الرغم من أنها تذكر Xrange على أنها سريعة جدًا - مما يجعلني أعتقد أنه قد ينجح. سيكون تحويل إنشاء المصفوفة إلى مولد قليلاً من العمل (معرفتي بالمولدات صدئة للغاية) ، لذلك أريد أن أعرف ما إذا كان هذا يعمل مقدمًا. قون

البديل الذي يمكنني رؤيته هو عمل عينة عشوائية عبر XRANGE ، وإنشاء الكائنات التي يتم اختيارها بالفعل بواسطة الفهرس. هذا ليس نظيفًا للغاية ، لأن المؤشرات التي تم إنشاؤها تعسفية وغير ضرورية ، وسأحتاج إلى منطق اختراق إلى حد ما لدعم هذا في طريقة GenerateHugeArray الخاصة بي.

للحصول على نقاط المكافأة: كيف تعمل العينة العشوائية فعليًا؟ على وجه الخصوص ، كيف يعمل إذا لم يكن يعرف حجم السكان مقدمًا ، كما هو الحال مع المولدات مثل Xrange؟

هل كانت مفيدة؟

المحلول

لا يبدو أن هناك طريقة تتجنب معرفة كيفية تعيين المؤشرات لتباديلاتك. إذا كنت لا تعرف هذا ، كيف يمكنك إنشاء كائن عشوائي من صفيفك؟ يمكنك إما استخدام الخدعة باستخدام xrange() لقد اقترحت نفسك ، أو تنفيذ فصل يحدد __getitem__() و __len__() الأساليب والتمرير والكائن من هذه الفئة كما population حجة ل random.sample().

بعض التعليقات الإضافية:

  • إن تحويل CreateHugeArray () إلى مولد لن يشتري لك أي شيء - random.sample() لن يعمل بعد الآن. يحتاج إلى كائن يدعم len().

  • لذلك يفعل تحتاج إلى معرفة عدد العناصر في السكان مباشرة من البداية.

  • ال تطبيق يتميز خوارزميتين مختلفتين ويختاران تلك التي ستستخدم ذاكرة أقل. لصغيرة نسبيا k (أي ، في الحالة الموجودة) ، سيحفظ ببساطة المؤشرات التي تم اختيارها بالفعل في أ set وقم باختيار عشوائي جديد إذا ضرب أحدهم.

تحرير: سيكون نهج مختلف تمامًا للتكرار على جميع التباديل مرة واحدة ويقرر كل التقليب إذا كان ينبغي تضمينه. إذا كان إجمالي عدد التباديل n وتود الاختيار k منهم ، يمكنك الكتابة

selected = []
for i in xrange(n):
    perm = nextPermutation()
    if random.random() < float(k-len(selected))/(n-i):
        selected.append(perm)

هذا سيختار بالضبط k التباديل عشوائيا.

نصائح أخرى

يمكنك إنشاء قائمة بفهارس الصفيف مع عينة ثم إنشاء الكائنات وفقًا للنتائج:

def get_object(index):
    return MyClass(index)

أو شيء من هذا القبيل. ثم استخدم عينة لإنشاء الفهارس التي تحتاجها واتصل بهذه الوظيفة بهذه الفهارس:

objs = map(get_object, random.sample(range(length), 0.001 * length))

هذا غير مباشر بعض الشيء كما هو الحال فقط في قائمة من قائمة فهارس الصفيف الممكنة.

شرح كيف يعمل عشوائي.

random.sample(container, k) سيعود عدد القيم K بشكل عشوائي من الحاوية. نظرًا لأن المولد أمر لا يُنسى مثل القوائم والطائبة والمفاتيح أو القيم في الرسائل ، فإنه سوف يتكرر من خلال الحاوية ثم يأخذ هذه العناصر العشوائية.

على سبيل المثال random.sample(xrange(111),4) سيعود شيئًا مثل [33,52,111,1] كما k = 4 بمعنى 4 أرقام عشوائية من مولد Xrange حتى 111.

أظن أن الوظيفة CreateHugeArray () تحتوي على قطعة من التعليمات البرمجية المتكررة مرة واحدة لكل كائن يتم إنشاؤه. وأعتقد أن الكائنات يتم إنشاؤها من نوع من القيمة أو البذور الأولية ، وفي هذه الحالة ، يبدو CreateHugeArray () شيئًا من هذا القبيل:

def createHugeArray( list_of_seeds ):
  huge_array = []                  
  for i in list_of_seeds:
    my_object = makeObject( i )
    huge_array.append( my_object )           
  return huge_array

(لقد استخدمت قوائم غير صفائف ، لكنك تحصل على الفكرة.)

للقيام بأخذ العينات العشوائية قبل إنشاء الكائنات فعليًا ، ما عليك سوى إضافة سطر ينشئ رقمًا عشوائيًا ، ثم قم بإنشاء الكائن فقط إذا كان الرقم العشوائي أقل من عتبة معينة. قل أنك تريد فقط كائن واحد بألف. Random.Randint (0،999) يعطي رقمًا من 0 إلى 999 - لذلك قم بإنشاء كائن فقط إذا حصلت على صفر. يصبح الرمز أعلاه:

import random

def createHugeArray( list_of_seeds ):
  huge_array = [] 

  for i in list_of_seeds:
    die_roll = random.randint(0,999)

    if( die_roll == 0 ):
      my_object = makeObject( i )
      huge_array.append( my_object ) 
  return huge_array

بالطبع إذا كان تخميني حول كيفية عمل الكود الخاص بك خطأ ، فهذا أمر غير مجدي بالنسبة لك ، وفي هذه الحالة آسف ونتمنى لك التوفيق :-)

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