我正在编写一个程序,该程序一次从目录中获取一个文件.dat
,验证某些条件,如果验证正常,则将文件复制到另一个目录。
下面的代码显示了我如何导入文件并创建列表列表。我在执行验证步骤时遇到问题。我尝试使用for
循环,但是当设置 if 条件时,对列表列表中的元素进行操作似乎是不可能的。
特别是,我需要连续元素matrix[i][3]
和matrix[i+1][3]
之间的差异小于 5。
for filename in glob.glob(os.path.join(folder_path, '*.dat')):
with open(filename, 'r') as f:
matrix =[]
data = f.readlines()
for raw_line in data:
split_line1= raw_line.replace(":",";")
split_line2= split_line1.replace("n","")
split_line3 = split_line2.strip().split(";")
matrix.append(split_line3)
你好,欢迎来到堆栈溢出。
您没有提供数据文件的示例。查看您的代码后,我假设您的数据如下所示:
9;9;7;5;0;9;5;8;4;2
9;1;1;5;1;3;4;1;8;7
2;8;4;5;5;2;1;4;6;4
6;4;1;5;5;8;1;4;6;1
0;1;0;5;7;1;7;4;1;9
4;9;6;5;3;2;6;2;9;6
8;0;6;0;8;9;3;1;6;6
几点一般性评论:
- 要解析 csv 文件,请使用 csv 模块。它易于使用,并且比编写自己的解析器更不容易出错。
- 如果你做大量的数据处理和矩阵计算,你想看看熊猫和numpy库。在普通 Python 中逐行处理矩阵的速度要慢几个数量级。
我了解您对验证步骤的描述如下:
如果所有连续元素,则矩阵匹配
matrix[i][3]
和matrix[i+1][3]
相差不到 5。
我建议的代码如下所示:
import csv
from glob import glob
from pathlib import Path
def read_matrix(fn):
with open(fn) as f:
c = csv.reader(f, delimiter=";")
m = [[float(c) for c in row] for row in c]
return m
def verify_condition(matrix):
col = 3
pairs_of_consecutive_rows = zip(matrix[:-1], matrix[1:])
for row_i, row_j in pairs_of_consecutive_rows:
if abs(row_i[col] - row_j[col]) >= 5:
return False
return True
if __name__ == '__main__':
folder_path = Path("../data")
for filename in glob(str(folder_path / '*.dat')):
print(f"processsing {filename}")
matrix = read_matrix(filename)
matches = verify_condition(matrix)
if matches:
print("match")
# copy_file(filename, target_folder)
我不打算详细介绍函数read_matrix
。请注意,我使用语句将字符串转换为浮点数float(c)
以便以后能够进行数值计算。
我通过使用zip
同时迭代 'matrix[:-1]and 'matrix[1:]
来迭代所有连续的行。在此示例中查看zip
的效果:
>>> list(zip("ABC", "XYZ"))
[('A', 'X'), ('B', 'Y'), ('C', 'Z')]
以及[:-1]
指数和[1:]
指数的影响:
>>> "ABC"[:-1], "ABC"[1:]
('AB', 'BC')
当verify_condition
找到相差至少为 5 的前两行时,它将返回 false。
我相信这段代码应该可以帮助您继续。
PS:我无法抗拒使用pathlib
库,因为我真的更喜欢在我的脚本中看到像folder / subfolder / "filename.txt"
这样的代码而不是path.join(folder, subfolder, "filename.txt")
。