我有多个不同的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()
但这并不奏效。有什么建议吗?
最好使用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
您可以将其扩展到一个集群。但是,如果您不能部署集群,我将在下面重复我的评论,您应该考虑使用ApacheArrow的解决方案。
注意:concat
步骤将生成UserWarning
。为了确保你可以忽略它,你必须做一些基础工作,并确保所有CSV对齐(如在相同数量的行中(。如果不是这样,你需要在合并前对它们进行预处理。
任何与预处理或箭头相关的帮助都应该是单独的问题。
第2版:
以下是另一种更适合大文件的基于熊猫的方法:
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()
。
在不知道数据形状的情况下说得更多很巧妙,但如果每个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))
示例中的代码很慢,因为您一直在循环中打开和关闭(以及从磁盘读取(同一个文件。可能应该是:
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])