逐行创建 python 中的大型数据集

Creating a large dataset in python line-by-line

为了完成我的毕业论文,我需要创建一个扑克动作数据集来测试模型。我写了一个函数,它读取带有 information about the hand 和 returns 一个 list 的文本文件,我将其附加到 pandas 数据框。

我有大约 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,所以我可能在某个地方犯了一个大错误,导致它花费的时间比需要的多得多,但我找不到它。

另一件困扰我的事情是它消耗不到 1GB 的内存,而它在 16GB 的机器上 运行。我考虑过强制它使用更多内存,但显然 python 没有内存限制,所以我猜这只是错误的代码

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

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

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

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

此外,您似乎认为自动使用更多 RAM 会使您的程序更快。这不是真的。通常你可以做出权衡,包括更快 run-time 和更多 RAM 使用,但同一台机器上的相同代码块总是花费几乎完全相同的时间和 RAM 运行。

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

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'))