Обработка значений соответствующих полей в нескольких CSV-файлах с использованием Python

#python #csv

Вопрос:

Я пытался найти минимальное и максимальное количество соответствующих значений в нескольких файлах CSV.

Хотя на самом деле у меня есть несколько файлов с несколькими столбцами в каждом из них, вот три простых примера файлов:

 a1,a2,a3
b1,b2,b3
c1,c2,c3

p1,p2,p3
q1,q2,q3
r1,r2,r3

x1,x2,x3
y1,y2,y3
z1,z2,z3
 

Использование python, как создать список соответствующих значений, пример L1 = [a1,p1,x1,...] , L2=[a2,p2,x2,..] и так далее.

Любой простой способ создать файл CSV, содержащий минимальное и максимальное количество соответствующих значений вышеуказанных входных файлов

 min(a1,p1,x1)-max(a1,p1,x1), min(a2,p2,x2)-max(a2,p2,x2), min(a3,p3,x3)-max(a3,p3,x3)
min(b1,q1,y1)-max(b1,q1,y1), min(b2,q2,y2)-max(b2,q2,y2), min(b3,q3,y3)-max(b3,q3,y3) 
min(c1,r1,z1)-max(c1,r1,z1), min(c2,r2,z2)-max(c2,r2,z2), min(c3,r3,z3)-max(c3,r3,z3) 
 

Любая помощь будет очень признательна

Ответ №1:

Если вы хотите сделать это на чистом Python, вы можете сделать что-то вроде этого:

 import csv
from contextlib import ExitStack

in_filenames = ["file1.csv", "file2.csv", "file3.csv"]
out_filename = "file.csv"

with ExitStack() as stack:
    readers = [
        csv.reader(stack.enter_context(open(filename, "r")))
        for filename in in_filenames
    ]
    writer = csv.writer(stack.enter_context(open(out_filename, "w")))
    while True:
        try:
            rows = zip(*[next(reader) for reader in readers])
        except StopIteration:
            break
        else:
            out_row = []
            for numbers in rows:
                numbers = [float(number) for number in numbers]
                out_row.append(min(numbers) - max(numbers))
            writer.writerow(out_row)
 

Если вы можете использовать Панд, это немного проще:

 import pandas as pd

in_filenames = ["file1.csv", "file2.csv", "file3.csv"]
out_filename = "file.csv"

dfs = [
    pd.read_csv(filename, header=None)
    for filename in in_filenames
]
dfs = [
    pd.concat((df[col] for df in dfs), axis=1)
    for col in dfs[0].columns
]
df = pd.concat(
    (df.min(axis=1) - df.max(axis=1) for df in dfs),
    axis=1
)
df.to_csv(out_filename, index=False, header=False)
 

(Возможно, есть более простой способ, я просто пока его не вижу.)

Комментарии:

1. Спасибо, Тимус, за быстрый ответ. Это было очень полезно