python批量处理文件和数据


path ='.../data0ape'
def get_filelist(dir):
    Filelist = []
    for home, dirs, files in os.walk(path):
        for filename in files:
            # 文件名列表,包含完整路径
            Filelist.append(os.path.join(home, filename))
            # # 文件名列表,只包含文件名
            # Filelist.append( filename)
    return Filelist
Filelist = get_filelist(dir)
print(len( Filelist))
for file in  Filelist :
        #print(file)
        txtfile = open(file, "r")
        lineStr1 = txtfile.readline()
        word = lineStr1[13:].split(" ")[0]
        #df
        files = pd.read_csv(file,sep='\s+',header = None, skiprows= 8,keep_default_na=False)
        data = pd.DataFrame(files)
        data['time'] = data[1].apply(lambda x:x[0:8])
        data_new = data
        data_new[1] = data_new['time']
        data_new = data_new.groupby(by = 'time').mean()
        data_new = data_new.reset_index(drop=False)
        df1 = data_new.iloc[:,:2 ]
        dftest = pd.DataFrame({'time': pd.date_range(start= df1['time'][0], end=df1['time'].iloc[-1], freq='S')})
        df1['time'] = df1['time'].astype('str')
        start = df1['time'][0]
        end = df1['time'][(len(df1) - 1)]
        time = pd.date_range(start=start, end=end, freq='S')
        str1 = time.strftime("%Y-%m-%d %H:%M:%S").to_list()
        time2 = [x.split(' ')[1] for x in str1]
        df2 = pd.DataFrame({'time': time2})
        df3 = pd.merge(df1, df2, on='time', how="right")
        df4 = df3.drop('time', axis = 1)
        #add id
        df4.loc[-1] = word
        df4.index = df4.index + 1
        df4 = df4.sort_index()

本人想使用上述代码块实现————从某文件夹子文件夹的.txt提取要素作为数据文件,在运行时“lineStr1 = txtfile.readline()”报错,'utf-8' codec can't decode byte 0x88 in position 296: invalid start byte,修改‘r’为‘encoding='ISO-8859-1'后,files = pd.read_csv(file,sep='\s+',header = None, skiprows= 8,keep_default_na=False)又报错Error tokenizing data. C error: Expected 3 fields in line 10, saw 9。源代码在单步调试时是可以运行的,最后我想实现所有从file提取的df整合到一个df文件里面。

该回答引用GPTᴼᴾᴱᴺᴬᴵ

关于第一个问题,'utf-8' codec can't decode byte 0x88 in position 296: invalid start byte,这个错误可能是因为文本文件的编码格式不是utf-8,可以尝试使用其他编码格式打开文件,比如'ISO-8859-1',使用如下代码:

txtfile = open(file, "r", encoding='ISO-8859-1')

关于第二个问题,Error tokenizing data. C error: Expected 3 fields in line 10, saw 9,这个错误是因为在读取txt文件时,某一行的字段数目与指定的分隔符sep='\s+'不符合。可以尝试使用pandas的error_bad_lines参数跳过错误行,如下:

files = pd.read_csv(file, sep='\s+', header=None, skiprows=8, keep_default_na=False, error_bad_lines=False)

最后关于整合到一个df文件里面,可以先定义一个空的DataFrame,然后在每次循环读取到的文件中,将df4追加到这个空DataFrame中,如下:

result_df = pd.DataFrame()  # 定义一个空的DataFrame用于存放结果
for file in Filelist:
    # 读取文件、处理数据
    ...
    # 将df4追加到结果DataFrame中
    result_df = result_df.append(df4, ignore_index=True)
# 保存结果到文件
result_df.to_csv("result.csv", index=False)

最后将结果保存到result.csv文件中。

该回答引用ChatGPT

修改后的 ,试一下
如果报错可以找我

import os
import pandas as pd

def get_filelist(path):
    Filelist = []
    for home, dirs, files in os.walk(path):
        for filename in files:
            # 文件名列表,包含完整路径
            Filelist.append(os.path.join(home, filename))
    return Filelist

path ='.../data0ape'
file_list = get_filelist(path)
print(len(file_list))

df_combined = pd.DataFrame()

for file in file_list:
    # 读取 txt 文件并提取要素
    with open(file, 'r', encoding='ISO-8859-1') as txtfile:
        lineStr1 = txtfile.readline()
        word = lineStr1[13:].split(" ")[0]

    # 读取 csv 文件并整理数据
    files = pd.read_csv(file, sep='\s+', header=None, skiprows=8, keep_default_na=False, error_bad_lines=False)
    data = files.iloc[:, :2]
    data['time'] = data[1].apply(lambda x: x[0:8])
    data = data.groupby(by='time').mean()
    data = data.reset_index(drop=False)
    df1 = data.iloc[:, :2]
    dftest = pd.DataFrame({'time': pd.date_range(start=df1['time'][0], end=df1['time'].iloc[-1], freq='S')})
    df1['time'] = df1['time'].astype('str')
    start = df1['time'][0]
    end = df1['time'][(len(df1) - 1)]
    time = pd.date_range(start=start, end=end, freq='S')
    str1 = time.strftime("%Y-%m-%d %H:%M:%S").to_list()
    time2 = [x.split(' ')[1] for x in str1]
    df2 = pd.DataFrame({'time': time2})
    df3 = pd.merge(df1, df2, on='time', how="right")
    df3 = df3.drop('time', axis=1)

    # 添加要素列
    df3['id'] = word

    # 按时间合并数据
    if df_combined.empty:
        df_combined = df3
    else:
        df_combined = pd.merge(df_combined, df3, on='time', how='outer')

print(df_combined)


参考GPT和自己的思路,错误“utf-8' codec can't decode byte 0x88 in position 296: invalid start byte”表明您尝试读取的文件未以 UTF-8 编码。 通过将 'r' 更改为 'encoding='ISO-8859-1'' 您可能已经解决了这个问题。 但是,错误“Error tokenizing data.C error: Expected 3 fields in line 10, saw 9”表明文件中的数据结构存在问题。 似乎脚本期望读取的字段数与文件第 10 行中实际存在的字段数不同。

以下是一些尝试的建议:

检查数据文件的结构以确保它是预期的格式。
尝试在发生错误的行打印出文件的内容,以查看文件的实际内容是什么样的。
尝试修改脚本以处理具有不同字段数的文件。 例如,您可以添加一个 if 语句来检查每行中的字段数,并处理字段数不是脚本预期的情况。
要将所有数据框组合成一个数据框,您可以使用 pandas.concat() 函数。 下面是一个示例,说明如何修改代码以连接所有数据框:

import os
import pandas as pd

path ='.../data0ape'

def get_filelist(path):
    Filelist = []
    for home, dirs, files in os.walk(path):
        for filename in files:
            # 文件名列表,包含完整路径
            Filelist.append(os.path.join(home, filename))
            # # 文件名列表,只包含文件名
            # Filelist.append( filename)
    return Filelist

Filelist = get_filelist(path)
all_data = pd.DataFrame()  # 创建一个空数据框

for file in Filelist:
    with open(file, "r", encoding='ISO-8859-1') as txtfile:
        lineStr1 = txtfile.readline()
        word = lineStr1[13:].split(" ")[0]
        files = pd.read_csv(file, sep='\s+', header=None, skiprows=8, keep_default_na=False, error_bad_lines=False)
        data = pd.DataFrame(files)
        data['time'] = data[1].apply(lambda x:x[0:8])
        data_new = data.groupby(by='time').mean().reset_index(drop=False)
        df1 = data_new.iloc[:, :2]
        dftest = pd.DataFrame({'time': pd.date_range(start=df1['time'][0], end=df1['time'].iloc[-1], freq='S')})
        df1['time'] = df1['time'].astype('str')
        start = df1['time'][0]
        end = df1['time'][(len(df1) - 1)]
        time = pd.date_range(start=start, end=end, freq='S')
        str1 = time.strftime("%Y-%m-%d %H:%M:%S").to_list()
        time2 = [x.split(' ')[1] for x in str1]
        df2 = pd.DataFrame({'time': time2})
        df3 = pd.merge(df1, df2, on='time', how="right")
        df4 = df3.drop('time', axis=1)
        df4.loc[-1] = word
        df4.index = df4.index + 1
        df4 = df4.sort_index()
        
        all_data = pd.concat([all_data, df4])  # 将当前文件的数据框添加到空数据框中
        
print(all_data.head())  # 打印所有数据的前几行

没有看到你从文件夹里只过滤出.txt文件的动作,你的代码是读所有的文件,可能读的不是.txt文件呢

pandas使用read_csv读取时,将第一行视为表头。当第二行的数据列数大于表头列数时候,就会报错。此时有两种解决办法
1、使用error_bad_lines=False,数据列数大于表头列数的那一行就会被视为坏行而被抛弃,不会显示在read_csv读取的数据中。

files = pd.read_csv(file, sep='\s+', header=None, skiprows=8, keep_default_na=False, error_bad_lines=False)

2、用names参数自定义表头名字

files = pd.read_csv(file, sep='\s+', header=None, skiprows=8, keep_default_na=False,names =['1','2','3','4','5','6','7','8','9'])#与具体的列数有关

您可以使用Pandas的concat()函数将所有DataFrame对象合并到一个DataFrame中

以下答案基于ChatGPT与GISer Liu编写:

  1. 关于第一个问题,'utf-8' 编解码器无法解码的问题,可以尝试修改文件读取方式,使用'rb'(二进制)的方式读取,然后再解码成字符串,如下所示:

    txtfile = open(file, "rb")
    lineStr1 = txtfile.readline().decode('ISO-8859-1')
    
  2. 关于第二个问题,错误标记化数据的问题,可能是由于在读取文件时指定了错误的分隔符或跳过行数。建议先打印出文件的内容进行查看,确认文件格式是否正确。另外,可以尝试使用不同的分隔符或跳过不同的行数,或者手动修改数据文件使其符合读取要求。

  3. 最后关于整合所有的 DataFrame,可以在每次循环中将 df4 添加到一个列表中,然后使用 pandas 的 concat 方法将所有的 DataFrame 拼接在一起,如下所示:

    dfs = []
    for file in Filelist:
     # 这里输入读取文件代码 
     dfs.append(df4)
    df_all = pd.concat(dfs, ignore_index=True)