打开许多txt文件,并分为两个df

时间:2019-07-10 16:03:29

标签: python pandas loops import

我需要根据它们的名称和其中包含的文件夹名称,将数百个.txt文件打开并处理为两个数据帧。

文件夹结构:

我有一个文件夹,其中包含许多子文件夹,每个子文件夹都以记录数据的日期命名,格式为:YYY-MM-DD,例如:2019-0-14

文件结构:

在上述每个文件夹中,有576个文件。有两组测量值(基于2个位置),在每24小时内每5分钟进行一次测量(12 * 24 * 2 = 576)。这些文件的名称如下:

hhmmssILAC3octf.txt  for the indoor location
hhmmssOLAC3octf.txt  for the outdoor location

hhmmss是每个5分钟文件的小时,分​​钟和秒,IL是在室内,OL是在户外。

文件内容:

每个文件包含5行数据,每分钟一行。此数据是相同类型的数据,并且长度相同,用逗号分隔。

我要实现的目标:

我需要创建两个数据框:每个位置一个,以日期(文件夹名称)和时间(文件名称和位置[行1:5])作为日期时间索引,该数据框基于包含在其中的文件夹,文件名和.txt中的行号

我还需要对所有列/变量进行重命名,一旦导入它们便使用相同的名称,但要根据其位置在室内或室外添加前缀。例如:indoor_20hz。

我本人使用Python和Pandas,但从未尝试解决此类问题。请有人能指出正确的方向...

谢谢。

2 个答案:

答案 0 :(得分:1)

您可以从以下代码开始:

import os
import fnmatch

start_dirctory='.'  # change this
df_result= None
for path, dirs, files in os.walk(start_dirctory):
        for file in fnmatch.filter(files, '*.txt'):
                full_name=os.path.join(path, file)
                df_tmp= pd.read_csv(full_name)
                # add the line number
                df_tmp['line_number']= range(df_tmp.shape[0])
                # add the code here that generates the infos 
                # you additionally need here to the df
                # then concatenate the files together
                if df_result is None:
                    df_result= df_tmp
                else:
                    df_result= pd.concat([df_result, df_tmp], axis='index', ignore_index=True)

因此,您应该在df_result中拥有所有文件的内容。但是您需要确保文件具有相同的列结构,否则需要在上面进行修复。您还需要添加所需的其他信息,以代替“#将此处需要的信息添加到df”。

答案 1 :(得分:0)

我的最终解决方案,尽管我肯定这不是获得最终结果的最优雅方法:

import os
import fnmatch
import pandas as pd

start_dirctory='DIR'  # change this
df_result= None
for path, dirs, files in os.walk(start_dirctory):
        for file in fnmatch.filter(files, '*.txt'):
                full_name=os.path.join(path, file)
                df_tmp= pd.read_csv(full_name, header=None)
                df_tmp['date']=os.path.basename(path)
                df_tmp['file']=os.path.basename(file)
                # df_tmp.set_index([df_tmp['date'], df_tmp['time']], inplace=True)
                # add the line number
                df_tmp['line_number']= range(df_tmp.shape[0])
                # add the code here that generates the infos 
                # you additionally need here to the df
                # then concatenate the files together
                if df_result is None:
                    df_result= df_tmp
                else:
                    df_result= pd.concat([df_result, df_tmp], axis='index', ignore_index=True)

# Slice filename from 6 to 7 to get location
df_result['location'] = df_result['file'].str.slice(6,7)

# Slice filename from 0 to 6 to get time
df_result['time'] = df_result['file'].str.slice(0,6)

# Combine date and time and format as datetime
df_result['date'] = pd.to_datetime(df_result['date'] + ' ' + df_result['time'], errors='raise', dayfirst=False)

# Round all the datetimes to the nearest 5 min
df_result['date'] = df_result['date'].dt.round('5min')

# Add line number as minutes to the date
df_result['date'] = df_result['date'] + pd.to_timedelta(df_result['line_number'],unit='m')

del df_result['file']
del df_result['line_number']
del df_result['time']

# Make the date the index in df
df_result = df_result.set_index(df_result['date'])

# Delete date in df
del df_result['date']

# Change columns and rename df_result
df_result.columns = ['10hz', '12.5hz', '16hz', '20hz','25hz','31.5hz','40hz','50hz','63hz','80hz','100hz','125hz','160hz','200hz','250hz','315hz','400hz','500hz','630hz','800hz','1000hz','1250hz','1600hz','2000hz','2500hz','3150hz','4000hz','5000hz','6300hz','8000hz','10000hz']