我有多个不同的 csv 文件,每个文件代表一个功能。我需要创建一个新的 csv 文件,该文件包含每个单独的文件并将它们映射到新文件中的新列。
我尝试过这样的事情:
import csv
file = open("House_2_X.csv", 'a')
writer = csv.writer(file)
with open("House_2_TS copy/channel_1(TimeStamp).csv") as f:
for line in f:
with open("House_2_BOTH copy/channel_2(BOTH).csv", 'r') as f1:
for line1 in f1:
a = line1[12:]
line1 = a[:4]
writer.writerow([line, line1])
file.close()
但这不起作用。 有什么建议吗?
答案 0 :(得分:2)
最好使用 pandas
。由于您没有显示示例文件,假设每个文件都有一列,这样的操作是可行的。
cols = [pd.read_csv(f, squeeze=True) for f in file_paths]
df = pd.concat([cols], axis=1)
df.to_csv("newfile.csv")
编辑:
既然有关于大文件的评论,这里有一个 dask
的方法。
有 3 个如下所示的 CSV:
$ for f in *.csv; do cat $f; echo; done
abc
def
ghi
ABC
DEF
GHI
a_b_c
d_e_f
g_h_i
以下内容:
import dask.dataframe as dd
df = dd.read_csv("*.csv", header=None).squeeze()
df = dd.concat(list(df.partitions), axis=1) # see note below
df.compute() # this should return you to pandas
给我这个:
0 0 0
0 abc ABC a_b_c
1 def DEF d_e_f
2 ghi GHI g_h_i
您可以将其扩展到集群。但是,如果您无法部署集群,我将在下面重复我的评论,您应该查看使用 Apache Arrow 的解决方案。
注意: concat
步骤将生成 UserWarning
。为了确保您可以忽略它,您必须做一些基础工作并确保所有 CSV 对齐(例如,行数相同。如果不是这种情况,您需要在合并之前对它们进行预处理。
任何与预处理或箭头相关的帮助都应该是单独的问题。
EDIT2:
这是一种更适合大文件的基于熊猫的替代方法:
chunked_readers = [
pd.read_csv(f, chunksize=<size>, header=None, squeeze=True)
for f in file_paths
]
for i, dfs in enumerate(zip(*chunked_readers):
df = pd.concat(dfs, axis=1)
df.to_csv(f"merged_{i}.csv")
根据您的资源限制选择 chunksize
。为确保不会耗尽内存,您还可以在循环内调用 gc.collect()
。
答案 1 :(得分:1)
在不知道数据形状的情况下很难说更多,但是如果每个 csv 中的列名不同,这将起作用,我认为应该是这样,因为您说它们都有不同的特征。
import pandas as pd
import glob
csvs = glob.glob('path_to_folder_containing_all_your_csvs/*.csv')
df = pd.concat((pd.read_csv(s) for s in csvs))
答案 2 :(得分:1)
示例中的代码很慢,因为您在循环中不断打开和关闭(以及从磁盘读取)同一个文件。应该是:
with open("House_2_TS copy/channel_1(TimeStamp).csv") as f, open("House_2_BOTH copy/channel_2(BOTH).csv", 'r') as f1:
for line in f:
for line1 in f1:
line1 = line1[12:16]
writer.writerow([line, line1])
f1.seek(0)
也就是说,如果您希望新文件具有 len(f) * len(f1)
行。如果它适合内存以加快循环速度,您还可以将第二个文件行存储在列表中。
如果你不是故意嵌套循环,那么代码是
with open("House_2_TS copy/channel_1(TimeStamp).csv") as f, open("House_2_BOTH copy/channel_2(BOTH).csv", 'r') as f1:
for line,line1 in zip(f,f1):
line1 = line1[12:16]
writer.writerow([line, line1])