如何将代码应用于 zip 文件,同时更改输出 zip 文件夹中的文件类型?

问题描述 投票:0回答:1

我有一个代码试图在 python 中的 zip 文件上使用,我希望输出是另一个 zip 文件,但文件更改为 .txt 或 .csv。
我的代码运行没有错误,但无法更改文件类型,并且我无法确定内容是否正在更改。
我能够一次更改从 zip 中获取的单个 .psa 文件,结果是包含所需修改的 .csv 文件。

细分:
我有一个包含 .psa 文件的 zip 文件夹。
我有一个代码可以读取单个 .psa 文件并输出经过修改的 .csv。
我想将此代码应用于包含所有 .psa 文件的 zip 文件夹,而不是对单个文件手动执行此过程。
目前,适用于单个文件的代码要求我在代码中命名输出文件。 如果生成的文件具有与输入相同的名称,只是文件类型名称更改为 .csv,将会很有帮助。

奖励:如果 zip 文件夹的输出只是一个 .csv 文件,其中包含输出 zip 文件夹中所有输出文件的内容,那就更好了。我认为这可以解决命名问题。 (所以基本上只是一个文件输出而不是多个。)

下面是适用于单个文件的代码:此代码采用 .psa 文件并将其转换为 .csv,同时还更改内容。

import pandas as pd
import re

`fname = '1 Area 2 - store 15 group.psa'
df = pd.read_csv(fname, usecols=[0,1,2], header=None, names=['type','upc', 'num'])
store = re.search(r'store\s+(\d+)', fname).group(1)
df = df[df['type'] == 'prod'].drop(columns=['type','upc']).assign(store=store)
df.to_csv("output.csv", index=False) `

下面是我应用于 zip 文件的代码。结果是创建了一个新的 zip 文件,但其中的文件是相同的 .psa 文件类型。

import pandas as pd
import re
import zipfile
import os
 
input_zip_path = r'test.zip'
output_zip_path = 'results.zip'
 
def process_file(file_path):
    df = pd.read_csv(file_path, usecols=[0,1,2], header=None, names=['type','upc','num'])
    store = re.search(r'store\s+(\d+)',file_path).group(1)
    df = df[df['type']=='prod'].drop(columns=['type','upc']).assign(store=store)
    df.to_csv("name.csv", index=False)
    return df
 
with zipfile.ZipFile(input_zip_path, 'r') as zin, zipfile.ZipFile(output_zip_path, 'w') as zout:
    for file_info in zin.infolist():
        with zin.open(file_info) as f, open(file_info.filename, 'w') as fout:
            fout.write(str(f.read()))
        modified_df = process_file(file_info.filename)
        modified_df.to_csv(file_info.filename, index=False)
        zout.write(file_info.filename)
        os.remove(file_info.filename)

python pandas jupyter-notebook zip
1个回答
0
投票

TL;博士

zout.write(file_info.filename)
更改为
zout.write("name.csv")

故障

让我们分解一下这部分代码:

with zipfile.ZipFile(input_zip_path, 'r') as zin, zipfile.ZipFile(output_zip_path, 'w') as zout:
    for file_info in zin.infolist():
        with zin.open(file_info) as f, open(file_info.filename, 'w') as fout:
            fout.write(str(f.read()))
        modified_df = process_file(file_info.filename)
        modified_df.to_csv(file_info.filename, index=False)
        zout.write(file_info.filename)
        os.remove(file_info.filename)

因此,对于 zip 中的每个文件,您尝试:

  1. 读出zip文件中的每个文件
  2. 将内容写入 zip 之外的新文件
  3. 处理每个外部文件并将其转换为 CSV
  4. 将文件写入新的 zip 文件
  5. 删除外部文件

至少当前代码出错的地方是在步骤 3 和 4 之间。

当您处理外部文件时,您会执行以下操作

df.to_csv("name.csv", index=False)

这会将最终结果存储到新文件“name.csv”中。

但是,您写回 zip 的内容是:

zout.write(file_info.filename)

这里,

file_info.filename
不是您刚刚创建的文件
name.csv
,它只是原始的外部文件,这就是您最终得到的。

所以你可能想将其更改为:

zout.write("name.csv")

进一步改进

我还认为将文件写入外部的部分是不必要的,您也许可以使用 pandas 直接从 zip 内的文件中读取内容,如下所示:

with zin.open(file_info) as f:
    df = pd.read_csv(f, usecols=[0,1,2], header=None, names=['type','upc', 'num'])
© www.soinside.com 2019 - 2024. All rights reserved.