سؤال

هذه مشكلة كنت أرفع أدمغتي لفترة طويلة ، لذلك ستكون أي مساعدة رائعة. لديّ ملف يحتوي على عدة خطوط بالتنسيق التالي (كلمة ، وقت حدثت الكلمة ، وتواتر المستندات التي تحتوي على الكلمة المعطاة في المثال المحدد في الوقت المناسب). فيما يلي مثال على شكل الإدخال.

#inputfile
<word, time, frequency>
apple, 1, 3
banana, 1, 2
apple, 2, 1
banana, 2, 4
orange, 3, 1

لدي فئة بيثون أدناه اعتدت على إنشاء قواميس ثنائية الأبعاد لتخزين الملف أعلاه باستخدام المفتاح ، والتردد كقيمة:

class Ddict(dict):
    '''
    2D dictionary class
    '''
    def __init__(self, default=None):
            self.default = default

    def __getitem__(self, key):
            if not self.has_key(key):
                self[key] = self.default()
            return dict.__getitem__(self, key)


wordtime=Ddict(dict) # Store each inputfile entry with a <word,time> key
timeword=Ddict(dict) # Store each inputfile entry with a <time,word> key

# Loop over every line of the inputfile
for line in open('inputfile'):
    word,time,count=line.split(',')

    # If <word,time> already a key, increment count
    try:
        wordtime[word][time]+=count
    # Otherwise, create the key
    except KeyError:
        wordtime[word][time]=count

    # If <time,word> already a key, increment count     
    try:
        timeword[time][word]+=count
    # Otherwise, create the key
    except KeyError:
        timeword[time][word]=count

السؤال الذي لدي يتعلق بحساب أشياء معينة أثناء التكرار على الإدخالات في هذا القاموس ثنائي الأبعاد. لكل كلمة 'w' في كل مرة 't' ، احسب:

  1. عدد المستندات معكلمة "ث" داخل الوقت 't'. (أ)
  2. عدد المستندات بدونكلمة "ث" داخل الوقت 't'. (ب)
  3. عدد المستندات معكلمة "ث" الخارج الوقت 't'. (ج)
  4. عدد المستندات بدونكلمة "ث" الخارج الوقت 't'. (د)

يمثل كل عنصر من العناصر أعلاه إحدى خلايا جدول الطوارئ CHI-Square لكل كلمة ووقت. هل يمكن حساب كل هذه الأشياء داخل حلقة واحدة أو هل يجب القيام بها في وقت واحد؟

من الناحية المثالية ، أود أن يكون الإخراج ما هو أدناه ، حيث A ، B ، C ، D كلها العناصر المحسوبة أعلاه:

print "%s, %s, %s, %s" %(a,b,c,d)

في حالة ملف الإدخال أعلاه ، ستكون نتيجة محاولة العثور على جدول الطوارئ لكلمة "Apple" في الوقت "1" (3,2,1,6). سأشرح كيف يتم حساب كل خلية:

  • تحتوي المستندات "3" على "Apple" خلال الوقت "1".
  • هناك وثائق "2" خلال الوقت "1" لا تحتوي على "Apple".
  • يوجد مستند "1" يحتوي على "Apple" خارج الوقت "1".
  • هناك 6 مستندات خارج الوقت "1" لا تحتوي على كلمة "Apple" (1+4+1).
هل كانت مفيدة؟

المحلول

أضف أرقامك الأربعة لـ Apple/1 ما يصل إلى 12 ، أكثر من إجمالي عدد الملاحظات (11)! لا يوجد سوى 5 مستندات خارج الوقت "1" لا تحتوي على كلمة "Apple".

تحتاج إلى تقسيم الملاحظات إلى 4 مجموعات فرعية مفككة:
ج: Apple و 1 => 3
ب: غير التطبيق و 1 => 2
C: Apple وليس 1 => 1
D: غير التطبيق وليس 1 => 5

فيما يلي بعض التعليمات البرمجية التي تظهر طريقة واحدة للقيام بذلك:

from collections import defaultdict

class Crosstab(object):

    def __init__(self):
        self.count = defaultdict(lambda: defaultdict(int))
        self.row_tot = defaultdict(int)
        self.col_tot = defaultdict(int)
        self.grand_tot = 0

    def add(self, r, c, n):
        self.count[r][c] += n
        self.row_tot[r] += n
        self.col_tot[c] += n
        self.grand_tot += n

def load_data(line_iterator, conv_funcs):
    ct = Crosstab()
    for line in line_iterator:
        r, c, n = [func(s) for func, s in zip(conv_funcs, line.split(','))]
        ct.add(r, c, n)
    return ct

def display_all_2x2_tables(crosstab):
    for rx in crosstab.row_tot:
        for cx in crosstab.col_tot:
            a = crosstab.count[rx][cx]
            b = crosstab.col_tot[cx] - a
            c = crosstab.row_tot[rx] - a
            d = crosstab.grand_tot - a - b - c
            assert all(x >= 0 for x in (a, b, c, d))
            print ",".join(str(x) for x in (rx, cx, a, b, c, d))

if __name__ == "__main__":

    # inputfile
    # <word, time, frequency>
    lines = """\
    apple, 1, 3
    banana, 1, 2
    apple, 2, 1
    banana, 2, 4
    orange, 3, 1""".splitlines()

    ct = load_data(lines, (str.strip, int, int))
    display_all_2x2_tables(ct)

وهنا الإخراج:

orange,1,0,5,1,5
orange,2,0,5,1,5
orange,3,1,0,0,10
apple,1,3,2,1,5
apple,2,1,4,3,3
apple,3,0,1,4,6
banana,1,2,3,4,2
banana,2,4,1,2,4
banana,3,0,1,6,4
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top