在循环中创建然后合并到现有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...
"""
非常感谢任何建议。
答案 0 :(得分:1)
简单回答:将每个新的DataFrame放入一个字典中,以迭代为关键字。然后在最后合并它们。
我现在认为我理解发生了什么。您有一系列日志:L1, L2 ... LN
。从每个日志中提取两种文本文件a
和b
。所以你有L1a, L2a ... LNa
和L1b, L2b ... LNb
。您最后需要两个DataFrame,dfa
和dfb
。
首先,我将提取将文本文件转换为DataFrame的代码并将其转换为自己的函数。您不需要添加Iter
和Filename
列,因为这些列在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。
如果这不起作用,也许我误解了你的数据结构。如果您可以发布一个简单的工作示例,它将更容易提供帮助。