【问题标题】:Creating a large dataset in python line-by-line在python中逐行创建一个大型数据集
【发布时间】:2018-08-11 05:36:43
【问题描述】:

对于我的研究生论文,我需要创建一个扑克动作数据集来测试模型。我编写了一个函数,它使用information about the hand 读取一个文本文件并返回一个list,我将其附加到熊猫数据框。

我有大约 1500 个文件,每个文件包含 1500~3000 只手需要传递给这个函数,所以我的主脚本看起来像这样。

import os
os.chdir("C:/Users/jctda/OneDrive/Documentos/TCC/Programa")

import pandas as pd
from datagen import DataGenerator, EmptyLine
from poker.room.pokerstars import PokerStarsHandHistory
from functions import FindFold, GetFiles, GetShowers
#IMPORT DATAGEN AQUI

database = pd.DataFrame()

files = GetFiles('hand_texts')
for hand_text in files:
    text=open('hand_texts/' + hand_text)
    b=text.read()
    hands=b.split("\n\n\n\n\n")
    text.close()

    for i in range(1,len(hands)):

        try:

            hh = PokerStarsHandHistory(unicode(hands[i]))
            hh.parse()
            fold = FindFold(hh)

            if fold == 'showdown':
                for shower in GetShowers(hh):
                    database = database.append(DataGenerator(hh,shower,hand_text,i))
                    print('Success in parsing iteration ' + str(i) + ' from file' + hand_text)

        except:

            print('PARSER ERROR ON ITERATION [[' + str(i) + ']] FROM FILE [[' + hand_text + ']]')
            database = database.append(EmptyLine(hand_text,i))




database.to_csv('database2.csv') 

问题是运行几个小时后它变得非常慢。第一个文件大约需要 20 秒,但每次都会变慢,并且在运行 8 小时后开始每个文件需要一个多小时。我刚开始为这个项目学习 python,所以我可能在某个地方犯了一个大错误,导致它花费的时间比需要的多得多,但我找不到它。

让我烦恼的另一件事是,它在 16GB 的机器上运行时消耗的 RAM 不到 1GB。我考虑过尝试强制它使用更多内存,但显然 python 没有内存限制,所以我猜这只是糟糕的代码

谁能帮我弄清楚该怎么做?

【问题讨论】:

    标签: python python-2.7 dataset poker


    【解决方案1】:

    here 中所述,不要附加到循环内的数据帧,因为它非常低效。而是做这样的事情:

    files = GetFiles('hand_texts')
    
    database = []
    for hand_text in files:
        # as a sidenote, with contexts are helpful for these:
        with open('hand_texts/' + hand_text) as text:
            b=text.read()
    
        hands=b.split("\n\n\n\n\n")
    
        for i in range(1,len(hands)):
            try:
                hh = PokerStarsHandHistory(unicode(hands[i]))
                hh.parse()
                fold = FindFold(hh)
    
                if fold == 'showdown':
                    for shower in GetShowers(hh): 
                        database.append(DataGenerator(hh,shower,hand_text,i))
                        print('Success in parsing iteration ' + str(i) + ' from file' + hand_text)
    
            except:
                print('PARSER ERROR ON ITERATION [[' + str(i) + ']] FROM FILE [[' + hand_text + ']]')
                database.append(EmptyLine(hand_text,i))
    
    pd.DataFrame(database).to_csv('database2.csv'))
    

    【讨论】:

    • 非常感谢!但显然对于列表,您只需要使用database.append() 而不是database = database.append(),因为第二个返回None
    【解决方案2】:

    如果我错了,有人纠正我,但我相信附加到数据帧涉及迭代整个数据帧。这就是为什么随着数据框变长而需要更长的时间。我相信附加到文件并不涉及每次都读取整个文件。试试这个:

    with open('database2.csv', 'wa') as file: # 'wa' is write append mode
        file.write(relevant_data)
    

    这也会在缩进块的末尾自动关闭文件。

    另外,听起来您认为使用更多 RAM 会自动使您的程序更快。这不是真的。通常,您可以进行权衡,即更快的运行时间和更多的 RAM 使用量,但同一台机器上的相同代码块将始终花费几乎完全相同的时间和 RAM 来运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-12
      相关资源
      最近更新 更多