首页 > 解决方案 > 将大型文本文件读入数据框中以在 Python 中进行数据分析

问题描述

我知道以前有人问过类似的问题。但我仍然无法找出为我的程序处理数据的最佳方法

我有一个大文本文件(50,000 到 5,000,000 行文本)。我需要处理该文件的每一行并将其写入 Dataframe,以便我可以对它们进行一些数据分析。

数据框有 9 列,大部分是浮点数和一些字符串,没有。行数〜没有。输入文件中的行数

目前,我正在使用“with open..”逐行读取此文件,然后使用正则表达式提取所需的数据并将其作为一行写入数据框中。由于这是通过 For 循环,因此需要永远完成。

做这个的最好方式是什么 ?任何指针或示例程序?我什至应该使用数据框吗?

这是我的代码。

    def gcodetodf(self):


    with open(self.inputfilepath, 'r') as ifile:

        lflag = False
        for item in ifile:

            layermatch = self.layerpattern.match(item)
            self.tlist = item.split(' ')
            self.clist = re.split(r"(\w+)", item)

            if layermatch and (str(self.tlist[2][:-1]) == 'end' or int(self.tlist[2][:-1]) == (self.endlayer + 1)):
                break

            if (layermatch and int(self.tlist[2][:-1]) == self.startlayer) or lflag is True:
                lflag = True
                # clist = re.split(r"(\w+)", item)

                map_gcpat = {bool(self.gonepattern.match(item)): self.gc_g1xyef,
                             bool(self.gepattern.match(item)): self.gc_g1xye,
                             bool(self.gtrpattern.match(item)): self.gc_g1xyf,
                             bool(self.resetextpattern.match(item)): self.gc_g92e0,
                             bool(self.ftpattern.match(item)): self.gc_ftype,
                             bool(self.toolcompattern.match(item)): self.gc_toolcmt,
                             bool(self.layerpattern.match(item)): self.gc_laycmt,
                             bool(self.zpattern.match(item)): self.gc_g1z}

                map_gcpat.get(True, self.contd)()

    # print(self.newdataframe)

写入数据帧的示例函数如下所示:

def gc_g1xye(self):
    self.newdataframe = self.newdataframe.append(
        {'Xc': float(self.tlist[1][1:]), 'Yc': float(self.tlist[2][1:]), 'Zc': self.gc_z,
         'E': float(self.tlist[3][1:]),
         'F': None, 'FT': self.ft_var, 'EW': self.tc_ew, 'LH': self.tc_lh, 'Layer': self.cmt_layer},
        ignore_index=True)

示例输入文件:

........
G1 X159.8 Y140.2 E16.84505
G1 X159.8 Y159.8 E17.56214
M204 S5000
M205 X30 Y30
G0 F2400 X159.6 Y159.8
G0 X159.33 Y159.33
G0 X159.01 Y159.01
M204 S500
M205 X20 Y20
;TYPE:SKIN
G1 F1200 X140.99 Y159.01 E18.22142
G1 X140.99 Y140.99 E18.8807
G1 X159.01 Y140.99 E19.53999
G1 X159.01 Y159.01 E20.19927
M204 S5000
M205 X30 Y30
G0 F2400 X150.21 Y150.21
M204 S500
M205 X20 Y20
G1 F1200 X149.79 Y150.21 E20.21464
G1 X149.79 Y149.79 E20.23
G1 X150.21 Y149.79 E20.24537
G1 X150.21 Y150.21 E20.26073
M204 S5000
M205 X30 Y30
G0 F2400 X150.61 Y150.61
M204 S500
M205 X20 Y20
G1 F1200 X149.39 Y150.61 E20.30537
G1 X149.39 Y149.39 E20.35
G1 X150.61 Y149.39 E20.39464
..........

标签: python-3.xpandasdataframedata-analysislarge-data

解决方案


请注意 DataFrame.append 返回旧 DataFrame 的副本,其中添加了新行:它不能就地工作。逐行构造 DataFrame,然后使用 append 将在 O(n^2) 而不是 O(n) 中工作,如果你有 500 万行,这是相当糟糕的......

相反,您要做的是先将每一行附加到一个列表(字典列表很好),然后在完成所有解析后从中创建 DataFrame 对象。这会快得多,因为附加到列表是在恒定时间内完成的,因此您的总复杂度应该是 O(n)。

def gc_g1xye(self):
    self.data.append(
        {'Xc': float(self.tlist[1][1:]), 'Yc': float(self.tlist[2][1:]), 'Zc': self.gc_z,
         'E': float(self.tlist[3][1:]),
         'F': None, 'FT': self.ft_var, 'EW': self.tc_ew, 'LH': self.tc_lh, 'Layer': self.cmt_layer})

...

# Once the parsing is done:
self.newdataframe = pd.DataFrame(self.data)

这是最好的方法吗?对我来说,这似乎是一个好的开始。你应该使用 DataFrame 吗?从您所说的解析数据后要对数据执行的操作来看,DataFrame 听起来是个不错的选择。

作为一个不相关的随机提示,我推荐使用tqdm包来显示 for 循环的进度条。它非常易于使用,它可以帮助您判断是否值得等待该循环完成!


推荐阅读