为了批量处理文件,当然是想办法获取文件名,通过文件名形成文件路径从而批处理文件。
我以前绕过大弯,根据文件的命名规律,尤其是其中的数字递增规律来创建路径,自从发现os库里的listdir函数才知道自己有多蠢!
获取文件夹下所有文件的filename
files = os.listdir(r'C:\Users\didi\Desktop\work\perf\perform_1')
files是perform_1文件夹下所有文件的文件名形成的列表,再循环处理
all_data = []
for file in files:
file_path = 'C:/Users/didi/Desktop/work/perf/perform_1/' + file
encoding = get_encoding(file_path)
print(encoding)
f = open(file_path,encoding=encoding,errors='ignore')
new_data = []
for line in f.readlines():
# each_line = line.replace('\n','').split(',')
new_data.append(line)
new_data = new_data[1:]
for i in new_data:
all_data.append(i)
print(all_data)
# 获取文件编码类型
def get_encoding(file):
# 二进制方式读取,获取字节数据,检测类型
with open(file, 'rb') as f:
return chardet.detect(f.read())['encoding']
原因:有些编码是不兼容的,比如utf-8不能gbk的,GB2312不能解码GBK中的有些字符,我们需要知道文件本身的编码是什么
解决办法:
1、我们用上一个<获取文件编码>里的方法得到文件的编码,然后在open函数中设置encoding参数为文件自身的编码
encoding = get_encoding(file_path)
f = open(file_path,encoding=encoding)
2、对于中文字符的问题,我们已知底下的排序,按照编码方式包含的字符数的多少从少到多进行排序。因为GB2312编码的,我们可以试图用GBK或者更高的GB18030来打开。
GB2312 < GBK < GB18030
3、如果继续出现UnicodeDecodeError问题,则可以设置open函数中的error参数来控制错误的策略。
默认的参数就是strict,代表遇到非法字符时抛出异常; 如果设置为ignore,则会忽略非法字符; 如果设置为replace,则会用?取代非法字符; 如果设置为xmlcharrefreplace,则使用XML的字符引用
因此最终我是这么解决我的问题的:
df = pd.DataFrame()
files = os.listdir('intern/perform/')
for file in files:
file_path = 'perform/' + file
encoding = get_encoding(file_path) # get_encoding函数在上文
f = open(file_path, encoding=encoding,errors='replace')
data = pd.read_csv(f, skiprows=1, header=None)
df = df.append(data)
想设置成replace是因为我想知道未解码成功的字符在哪些位置,当然也可以选择ignore进行处理
最后也可以使用try/except语句,来捕捉异常并进行处理
发觉read_csv中有用的参数真的特别多,skiprows header sep parse_dates等等等等
而今天发现的error_bad_line参数是当你遇到特别异常的记录时,比如某一行的逗号较其他行多,导致数据的列数不匹配,这会引起异常,也不会返回相应的dataframe。而如果设置error_bad_line = False,可以选择返回的dataframe里面舍弃掉“bad_line”
而另一个与之相匹配的参数是warn_bad_lines,通过True or False选择是否提示跳过的line
data = pd.read_csv(f, skiprows=1, header=None,error_bad_lines = False,warn_bad_lines=True)
实际问题场景中,数据远比我们的想象的要脏很多,各种乱七八糟的想象不到的问题,而你眼中所见的也会迷惑你,不管怎样,兵来将挡水来土掩,养成良好的独立搜索解决问题的习惯,形成自己的知识结构以及对数据的敏感度和处理经验,是最重要的~