将列从现有 CSV 文件添加到 CSV 文件

时间:2021-07-23 00:02:14

标签: python csv export-to-csv

我有多个不同的 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()

但这不起作用。 有什么建议吗?

3 个答案:

答案 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])