Python在txt文件中循环以创建和合并数据帧

Python在txt文件中循环以创建和合并数据帧,python,pandas,Python,Pandas,在循环中创建并合并到现有数据帧的最佳方法是什么?我有一个日志文件(比如FILENAME1),它生成txt文件,提供我感兴趣的统计信息。我有一个脚本,可以循环并打开每个txt文件,并使用pd.read\u csv生成一个数据帧。然后,我使用xlsxwriter将每个数据帧粘贴到Excel 我遇到的问题是,每个txt文件都不同于下一个,当我对下一个文件(FILENAME2)执行相同操作时,我实际上是从一个全新的开始 例如,eash日志文件将生成以下内容: FILENAME1 Tech_Summary

在循环中创建并合并到现有数据帧的最佳方法是什么?我有一个日志文件(比如FILENAME1),它生成txt文件,提供我感兴趣的统计信息。我有一个脚本,可以循环并打开每个txt文件,并使用pd.read\u csv生成一个数据帧。然后,我使用xlsxwriter将每个数据帧粘贴到Excel

我遇到的问题是,每个txt文件都不同于下一个,当我对下一个文件(FILENAME2)执行相同操作时,我实际上是从一个全新的开始

例如,eash日志文件将生成以下内容:

FILENAME1
Tech_Summary.txt
Error_Totals.txt
然后我在一个循环中处理这些txt文件(对它们进行数据帧处理),然后粘贴到Excel并在完成后删除。然后,下一个文件生成具有相同文件名的类似文件:

FILENAME2
Tech_Summary.txt
Error_Totals.txt
我的循环需要工作,因为我每次打开一个新的txt文件时都会覆盖数据帧,因为合并函数并没有像我希望的那样工作。但我希望将每个迭代生成的数据帧与之前的迭代数据帧合并。。。但以每个txt文件为基础

这是我迄今为止的尝试

#Outline Dict items (make it generic for expansion)
TextExtractor={

    "Tech":{'txtfileID':'Tech_Summary',
                'lineskip':16,
                'linegrab':3,
                'linesplit':'% of Time in |;',
                'all_cols_labled':[1,'Tech','Percent','Null'],
                'cols_grab':['Tech','Percent'],
                'container':[],
                },      

        """ SAMPLE OF DF CREATED for "Tech"
           Tech    Percent Iter         Filename
        0  Type1        0  Iteration_1  Tech
        1  Type2      100  Iteration_1  Tech
        2  Type3        0  Iteration_1  Tech
        """

    "Errors":{'txtfileID':'Error_Totals',
                'lineskip':19,
                'linegrab':13,
                'linesplit':';',
                'all_cols_labled':['Scheme','Tot Errors','Tot Count','Percentage'],
                'cols_grab':['Scheme','Tot Errors','Tot Count','Percentage'],
                'container':[],
                },  

        """ SAMPLE OF DF CREATED for "Errors"
               Scheme  Tot Errors  Tot Count  Percentage    Iter        Filename
        0        -1        0           0     0              Iteration_1  Errors
        1        -2        0           0     0              Iteration_1  Errors
        2        -3        0           0     0              Iteration_1  Errors
        3        -4        0           0     0              Iteration_1  Errors
        4        -5       97           0     0              Iteration_1  Errors
        5        -6       55           0     0              Iteration_1  Errors
        """
}

looprun = 0
for textfile in os.listdir(resdir):
    if textfile.endswith('.txt'):
        for key in TextExtractor:
            #Set out rows and cols for Excel
            txtxlcol = XL_TextFileCoords['COLUMN']
            txtxlrow = XL_TextFileCoords['ROW']

            if TextExtractor[key]['txtfileID'] in textfile:
                #open each txt file and grab the selected data to make dataframe (DF)
                txt = pd.read_csv(resdir+'\\'+textfile, skiprows=TextExtractor[key]['lineskip'], nrows=TextExtractor[key]['linegrab'], header=None, sep=TextExtractor[key]['linesplit'], names=TextExtractor[key]['all_cols_labled'], usecols=TextExtractor[key]['cols_grab'], engine='python')
                #make dataframe
                txtDF = DataFrame(txt)
                #add iteration column to differentiate between each FILENAME
                txtDF['Iter'] = pd.Series(logID, index=txtDF.index)
                #add key column to DF to know what text file the data is from
                txtDF['Filename'] = pd.Series(key, index=txtDF.index)
                #convert DF to list ready to drop into each key (txt file) for later processing                 
                converttolist = txtDF.set_index(txtDF.index).T.to_dict('list')
                #Drop converted DF data into [key]['container'] for each txt file type based on key
                TextExtractor[key]['container'].append(converttolist)

                #write DF to Excel file
                txtDF.to_excel(writer, sheet_name=logID,startrow=txtxlrow, startcol=txtxlcol,index=False, header=False, columns=TextExtractor[key]['cols_grab'])
                #...do excel plotting stuff here

        #remove txt files from directory ready for next FILENAME (Iteration)
        os.remove(resdir+"/"+textfile)
    else:
        pass

for key in TextExtractor:
    print TextExtractor[key]['container']
因此,目前我正在将数据帧放入dict列表中,但我确实在寻找类似这种输出的东西。但是为了扩展而保留上面的循环功能

""" 
# FINAL DATAFRAME 1
Type    Iter        Percent
Type1   Iteration_1  0
        Iteration_2  100
        Iteration_3  0
Type2   Iteration_1  40
        Iteration_2  30
        Iteration_3  30
Type3   Iteration_1  15
        Iteration_2  55
        Iteration_3  30 

# FINAL DATAFRAME 2 
Scheme  Iter        Tot Errors  Tot Count  Percentage
-1      Iteration_1  0          5           30
        Iteration_2  0          5           12
        Iteration_3  7          7           12
-2      Iteration_1  7          9           18
        Iteration_2  6          0           9
        Iteration_3  5          2           17
-3      Iteration_1  5          4           17
        Iteration_2  6          1           12
        Iteration_3  9          6           21
-4      Iteration_1  8          7           18
        Iteration_2  4          8           12
        Iteration_3  4          3           84
-5      Iteration_1  3          2           91
etc...

"""

任何建议都将不胜感激。

简单回答:将每个新的数据帧放入字典,以迭代为关键。然后在末尾合并它们


我现在想我明白发生了什么。您有一系列日志:
L1、L2。。。项次
。从每个日志中提取两种文本文件,
a
b
。所以你有
L1a,L2a。。。LNa和L1b、L2b。。。LNb
。在末尾需要两个数据帧,
dfa
dfb

首先,我将把生成文本文件的代码提取到数据帧中,并将其转换为自己的函数。您不需要添加
Iter
Filename
列,因为这些列在数据帧中是相同的,我们将在其他地方处理这些信息

def df_from_txt(resdir, textfile, key):
    txt = pd.read_csv(
         resdir+'\\'+textfile, 
         skiprows=TextExtractor[key]['lineskip'], 
         nrows=TextExtractor[key]['linegrab'], 
         header=None, 
         sep=TextExtractor[key]['linesplit'], 
         names=TextExtractor[key]['all_cols_labled'],  
         usecols=TextExtractor[key]['cols_grab'], 
         engine='python')
     return DataFrame(txt)
现在提取逻辑已经从循环中分离出来,更容易看到逻辑。您还需要添加一个容器字典来保存文本文件解析的结果

dfs = {key: {} for key in TextExtractor.keys()}

for textfile in os.listdir(resdir):
    if textfile.endswith('.txt'):
        for key in TextExtractor:
            if TextExtractor[key]['txtfileID'] in textfile:
                df = df_from_txt(resdir, textfile, key)
                dfs[key][textfile] = df
现在您有了一个字典(
dfs
),它的键是从日志中提取的不同类型的文本文件(
“Tech”
“Errors”
)。这些值本身就是字典,其中键是文本文件的名称(如果
textfile
始终相同,则可以使用其他一些值作为键-原始函数中的
logID
来自何处?)。剩下的就是合并第二级词典的内容:

merged_dfs = {key: pd.concat(dfs[key]) for key in dfs.keys()}
现在您有了一个字典,其中键仍然是
“Tech”
“Errors”
,但值是单个数据帧


如果这不起作用,可能是我误解了您的数据结构。如果您可以发布一个简单的工作示例,那么会更容易提供帮助。

您想在什么意义上“合并”数据帧?您希望它们成为一个大型数据帧的一部分吗?这就是合并的建议,但是您显示的输出有单独的表。您好,ASGM,理想情况下,我希望根据txt文件名合并每个数据帧,因此,如果两个txt文件,则合并两个数据帧。然而,对于我的循环解决方案,我不确定这是否可行,可能不得不求助于一个大数据帧。不幸的是,如果我想以后添加更多的txt文件,我沿着循环路径使它更通用、更易于扩展对不起,我仍然很困惑-如果在流程结束时仍然需要两个单独的数据帧,那么“合并”数据帧是什么意思?两个文件,两个数据帧-合并发生在哪里?嗨,ASGM。为这一混乱道歉。基本上我有一个文件夹,里面有几个日志。我有一个单独的脚本,解析每个日志,然后生成包含有用信息的txt文件。然后,在我的示例代码中,我循环遍历每个txt文件(比如Tech_Summary.txt和Error_Totals.txt),生成一个数据框,并在这个过程中粘贴到Excel。最后,我将删除txt文件。我将移动到目录中的下一个日志,再次解析到txt文件(再次是Tech_Summary.txt和Error_Totals.txt),然后重复。因此,在10个日志的末尾,我希望得到两个单独的DFsI,我应该提到我将一个日志解析为txt,然后循环遍历txt文件来创建DFs,然后删除文本文件。然后转到目录中的下一个日志文件,将其解析为txt,再次遍历新的(但名称相同)txt文件,删除它们,依此类推。希望这是有意义的吗?嗨,AGSM,为延迟回复道歉,我这两周一直在度假。今天尝试了你的解决方案,它看起来像是按照我所寻找的路线工作。谢谢你的帮助和建议。