Python 3.x 在Python中将大型文本文件读入数据框进行数据分析

Python 3.x 在Python中将大型文本文件读入数据框进行数据分析,python-3.x,pandas,dataframe,data-analysis,large-data,Python 3.x,Pandas,Dataframe,Data Analysis,Large Data,我知道以前也有人问过类似的问题。但我仍然无法找到为我的程序处理数据的最佳方法 我有一个大的文本文件(50000到5000000行文本)。我需要处理此文件的每一行,并将其写入数据帧,以便对其进行数据分析 dataframe有9列,大部分是浮动的,输入文件中有一些字符串和行数~行数 目前,我正在使用“with open..”逐行读取此文件,然后使用regex提取所需的数据,并将其作为一行写入数据帧。由于这是通过一个For循环完成的,所以需要永远的时间 最好的方法是什么?有指针或示例程序吗?我应该使用

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

我有一个大的文本文件(50000到5000000行文本)。我需要处理此文件的每一行,并将其写入数据帧,以便对其进行数据分析

dataframe有9列,大部分是浮动的,输入文件中有一些字符串和行数~行数

目前,我正在使用“with open..”逐行读取此文件,然后使用regex提取所需的数据,并将其作为一行写入数据帧。由于这是通过一个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
..........

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

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

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


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

你能举例说明数据是什么样子的,以及你需要什么样的处理吗?首先将其读入数据帧,然后再进行处理可能更容易。@Lidae我已经用文件的样本块更新了文章。我需要对它进行数学运算。从col1和col2中取值,计算圆的面积;把所有的区域加在一起并绘制图表。好吧,我有点希望你能用read_csv之类的东西来解析。看到这一点,我认为解析必须是手动的。速度方面的瓶颈可能是self.newdataframe=self.newdataframe.append行。首先尝试附加到一个列表,然后使用该列表一次性创建数据帧,否则它将进行大量不必要的复制。这听起来是个好主意。但是,在接近结尾时,难道我不想拥有一个价值百万行的数据帧,以及一个列表的副本吗?我应该清除此列表吗?是的,我相信数据框会复制数据,因此如果空间有问题,您可以在以后删除此列表。
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)