我是python的新手,我有一个场景,其中存在多个拼写文件,文件名顺序排列。例如:一个文件夹中的par_file1,par_file2,par_file3等,最多100个文件。
我需要按顺序读取从file1开始的镶木地板文件,并将其写入单个csv文件。写入file1的内容后,应将file2的内容附加到没有标题的同一csv。请注意,所有文件都具有相同的列名,并且只有数据被拆分为多个文件。
我学会了使用pyarrow通过以下代码将单个实木复合地板转换为csv文件
将熊猫作为pd导入
df = pd.read_parquet('par_file.parquet')
df.to_csv('csv_file.csv')
但是我无法将其扩展为多个镶木文件循环并附加到单个csv。 熊猫有没有办法做到这一点?或任何其他方式可以提供很大帮助。谢谢。
答案 0 :(得分:6)
我遇到了这个问题,看熊猫是否可以本地读取分区的镶木地板数据集。我不得不说,当前的答案是不必要的冗长(使其难以解析)。我还认为,不断打开/关闭文件句柄然后根据大小扫描到它们的末尾并不是特别有效。
更好的选择是将所有实木复合地板文件读入单个DataFrame中,并写入一次:
from pathlib import Path
import pandas as pd
data_dir = Path('dir/to/parquet/files')
full_df = pd.concat(
pd.read_parquet(parquet_file)
for parquet_file in data_dir.glob('*.parquet')
)
full_df.to_csv('csv_file.csv')
或者,如果您真的只想追加到文件:
data_dir = Path('dir/to/parquet/files')
for i, parquet_path in enumerate(data_dir.glob('*.parquet')):
df = pd.read_parquet(parquet_path)
write_header = i == 0 # write header only on the 0th file
write_mode = 'w' if i == 0 else 'a' # 'write' mode for 0th file, 'append' otherwise
df.to_csv('csv_file.csv', mode=write_mode, header=write_header)
最后一个替代方案是在开始时附加以"a+"
模式打开目标CSV文件的每个文件,并在每次写入/追加时保持文件句柄扫描到文件末尾(我相信这是可行的,但是尚未实际上对其进行了测试):
data_dir = Path('dir/to/parquet/files')
with open('csv_file.csv', "a+") as csv_handle:
for i, parquet_path in enumerate(data_dir.glob('*.parquet')):
df = pd.read_parquet(parquet_path)
write_header = i == 0 # write header only on the 0th file
df.to_csv(csv_handle, header=write_header)
答案 1 :(得分:3)
这帮助我将所有实木复合地板文件加载到一个数据帧中
import glob
files = glob.glob("*.snappy.parquet")
data = [pd.read_parquet(f,engine='fastparquet') for f in files]
merged_data = pd.concat(data,ignore_index=True)
答案 2 :(得分:0)
如果要将文件复制到本地计算机上并运行代码,则可以执行以下操作。下面的代码假定您在与实木复合地板文件相同的目录中运行代码。它还假定文件的命名与您在上面提供的名称相同:“订单。例如:par_file1,par_file2,par_file3,依此类推,一个文件夹中最多包含100个文件。”如果您需要搜索文件,则需要使用glob
获取文件名,并显式提供要保存csv的路径:open(r'this\is\your\path\to\csv_file.csv', 'a')
希望对您有所帮助。
import pandas as pd
# Create an empty csv file and write the first parquet file with headers
with open('csv_file.csv','w') as csv_file:
print('Reading par_file1.parquet')
df = pd.read_parquet('par_file1.parquet')
df.to_csv(csv_file, index=False)
print('par_file1.parquet appended to csv_file.csv\n')
csv_file.close()
# create your file names and append to an empty list to look for in the current directory
files = []
for i in range(2,101):
files.append(f'par_file{i}.parquet')
# open files and append to csv_file.csv
for f in files:
print(f'Reading {f}')
df = pd.read_parquet(f)
with open('csv_file.csv','a') as file:
df.to_csv(file, header=False, index=False)
print(f'{f} appended to csv_file.csv\n')
您可以根据需要删除打印语句。
使用python 3.6
在pandas 0.23.3
中进行了测试
答案 3 :(得分:0)
对于那些尝试读取远程文件的人来说是一个小小的改变,这有助于更快地读取它(对远程文件来说,直接read_parquet对我而言这样做的速度要慢得多):
export function f(key: string): { key: string } { // <- return type
return { key };
}
interface WithKey {
key: string;
ignoreMe?: string;
}
const result: WithKey = f('myKey');
result.key; // works
result.ignoreMe // works (undefined)
不过会增加一点临时内存开销。
答案 4 :(得分:0)
我有类似的需求,我读到当前的 Pandas 版本支持将目录路径作为 read_csv 函数的参数。所以你可以像这样读取多个镶木地板文件:
import pandas as pd
df = pd.read_parquet('path/to/the/parquet/files/directory')
它将所有内容连接到单个数据帧中,以便您可以立即将其转换为 csv:
df.to_csv('csv_file.csv')
确保您根据文档具有以下依赖项: