Python循环通过txt文件来创建和合并Pandas Dataframes

时间:2015-06-24 14:47:11

标签: python pandas

在循环中创建然后合并到现有Dataframe的最佳方法是什么?我有一个日志文件(比如FILENAME1)生成txt文件给我感兴趣的统计数据。我有一个循环并打开每个txt文件的脚本,并使用pd.read_csv生成一个DataFrame。然后,我使用xlsxwriter将每个Dataframe粘贴到Excel。

我遇到的问题是每个txt文件与下一个文件不同,当我为下一个文件(FILENAME2)执行相同操作时添加到此文件中我实际上是从一个干净的平板开始。

例如,eash日志文件将生成说:

FILENAME1
Tech_Summary.txt
Error_Totals.txt

然后我在循环中处理这些txt文件(DataFrame)并粘贴到Excel并在完成后删除。然后下一个文件生成具有相同文件名的类似文件:

FILENAME2
Tech_Summary.txt
Error_Totals.txt

我的循环需要工作,因为每次打开一个新的txt文件时我都会覆盖Dataframe,因为合并功能没有像我希望的那样工作。但我希望将每个迭代生成的Dataframe与先前的迭代数据帧合并......但是基于每个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']

所以目前我将DataFrames放入一个dicts列表中,但我真的在寻找类似输出的东西。但是将循环功能保持在上面用于扩展

""" 
# 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...

"""

非常感谢任何建议。

1 个答案:

答案 0 :(得分:1)

简单回答:将每个新的DataFrame放入一个字典中,以迭代为关键字。然后在最后合并它们。

我现在认为我理解发生了什么。您有一系列日志:L1, L2 ... LN。从每个日志中提取两种文本文件ab。所以你有L1a, L2a ... LNaL1b, L2b ... LNb。您最后需要两个DataFrame,dfadfb

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

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",但值是单个DataFrame。

如果这不起作用,也许我误解了你的数据结构。如果您可以发布一个简单的工作示例,它将更容易提供帮助。