【问题标题】:Add new column in a csv file and manipulate on the on records在 csv 文件中添加新列并操作记录
【发布时间】:2015-12-12 15:50:41
【问题描述】:

我有 4 个名为 PV.csv、Dwel.csv、Sess.csv 和 Elap.csv 的 csv 文件。我在每个文件中有 15 列和大约 2000 行。首先,我想在每个文件中添加一个名为 Var 的新列,并用相同的文件名填充新列的单元格。因此,PV.csv 文件中的新列“Var”将被 PV 填充。其他 3 个文件也是如此。 之后,我想按如下方式操作所有文件。

最后我想根据 A_ID 和 B_ID 合并/加入这 4 个文件,并将记录写入一个新的 csv 文件名 finalFile.csv。 任何建议和帮助表示赞赏。

<p>PV.csv is as follows:</p>
   
A_ID      B_ID       LO       UP     LO      UP
103       321        0        402    
103       503        192      225    433     608   
106       264        104      258    334     408
107       197        6        32     113     258    

Dwell.csv如下:

   
A_ID      B_ID       LO       UP     LO      UP  
103       321        40       250    517     780
103       503        80       125    435     585     
106       264        192      525    682  
107       197        324      492    542     614    

Session.csv如下:

   
A_ID      B_ID       LO       UP     LO      UP 
103       321        75       350    370     850     
106       264        92       225    482     608  
107       197        24       92     142    

Elapsed.csv如下:

   
A_ID      B_ID       LO       UP     LO      UP 
103       321        5        35     75
103       503        100      225    333     408      
106       264        102      325    582  
107       197        24       92     142     214    

PV.csv 的第一个输出文件如下:

以同样的方式,其余三个文件将被新列填充,其中包含 ehrer 文件名、Dwell、Session 和 Elapsed:

   
A_ID    B_ID      Var   LO        UP     LO      UP
103     321       PV    0         402    
103     503       PV    192       225    433     608   
106     264       PV    104       258    334     408
107     197       PV    6         32     113     258 

最终输出文件如下:

finalFile.csv.

   
A_ID    B_ID      Var    LO        UP
103     321       PV     0         402
103     321       Dwel   40        250
103     321       Dwel   251       517
103     321       Dwel   518       780
103     321       Sess   75        350
103     321       Sess   351       370
103     321       Sess   371       850
103     321       Elap   5         35
103     321       Elap   36        75
103     503       PV     192       225
103     503       PV     226       433
103     503       PV     434       608
103     503       Dwel   80        125
103     503       Dwel   126       435
103     503       Dwel   436       585
103     503       Elap   100       225
103     503       Elap   226       333
103     503       Elap   334       408
106     264       PV     104       258
106     264       PV     259       334
106     264       PV     335       408
106     264       Dwel   192       525
106     264       Dwel   526       682
106     264       Sess   92        225
106     264       Sess   226       482
106     264       Sess   483       608
106     264       Elap   102       325
106     264       Elap   326       582
107     197       PV     6         32
107     192       PV     33        113
107     192       PV     114       258
107     192       Dwel   324       492
107     192       Dwel   493       542
107     192       Dwel   543       614
107     192       Sess   24        92
107     192       Sess   93        142
107     192       Elap   24        92
107     192       Elap   93        142
107     192       Elap   143       214

【问题讨论】:

  • 在文本中你说你有 15 个列,输入文件有 6 个,结果是 4 个。很抱歉,我不明白你真正想要做什么,以及为什么用 DictReader 阅读,添加每行一个键值并写回是不够的。
  • 谢谢。我不能在此处包含所有列。输入文件有更多列与 LO, UP, LO, UP..... 结果文件必须只有 4 列如上。
  • 您应该至少显示一个输入行,以便我们了解如何将其拆分为多行,或者是否只保留第一个 LO UP 字段。
  • 你的努力在哪里?阅读csv 模块的文档并尝试实现它。询问,如果您遇到困难,Google 不会提供帮助。
  • @Serge Ballesta,谢谢。每个 csv 文件包含一条记录/行包含一个或多个 LO、UP 值。但在最终文件中,我想使用一个 LO、UP 和其余的 LO UP 值将添加到下一行及其 A_ID 和 B_ID。就像,PV.csv 的第一行是这样写的,因为它只有一个 LO 和 UP。但是 PV.csv 的第二行被分成 3 行。您可以在 finalFile.csv 的第 10 行到第 13 行看到它。另外,使用2nd LO时,该值应该是之前的UP+1。

标签: python csv add


【解决方案1】:

你应该使用python内置的csv模块。

要创建最终的 csv 文件,您可以这样做。通读每个文件,将新列值添加到每一行并将其写入新文件

import csv

with open('finalcsv.csv', 'w') as outcsv:
    writer = csv.writer(outcsv)
    writer.writerow(['a','b','c','etc','Var']) # write final headers

    for filename in ['PV.csv','Dwel.csv','Sess.csv','Elap.csv']:
        with open(filename) as incsv:
            val = filename.split('.csv')[0]
            reader = csv.reader(incsv) # create reader object
            reader.next() # skip the headers

            for row in reader:
                writer.writerow(row+[val])

【讨论】:

  • 你好阿尼尔,谢谢。将 4 个 csv 文件的数据合并到一个 finacsv 文件中可以正常工作。在加入之前,我想在每个 csv 文件的 b 列之后添加一个新列“var”,以便我可以了解哪个文件产生了记录。然后我们可以加入/合并4个文件。最后,我想重新排列 LO、UP 值,如结果所示。
  • @Tofazzal 那么你应该使用 csv 模块的 DictReaderDictWriter 类。
【解决方案2】:

以下脚本应该可以帮助您入门:

from collections import defaultdict
from itertools import groupby
import csv

entries = defaultdict(list)
csv_files = [(0, 'PV.csv', 'PV'), (1, 'Dwell.csv', 'Dwel'), (2, 'Session.csv', 'Sess'), (3, 'Elapsed.csv', 'Elap')]

for index, filename, shortname in csv_files:
    f_input = open(filename, 'rb')
    csv_input = csv.reader(f_input)
    header = next(csv_input)

    for row in csv_input:
        row[:] = [col for col in row if col]    
        entries[(row[0], row[1])].append((index, shortname, row[2:]))

    f_input.close()

f_output = open('finalFile.csv', 'wb')
csv_output = csv.writer(f_output)
csv_output.writerow(header[:2] + ['Var'] + header[2:4])

for key in sorted(entries.keys()):
    for k, g in groupby(sorted(entries[key]), key=lambda x: x[1]):
        var_group = list(g)
        if len(var_group[0][2]):
            up = var_group[0][2][0]
            for entry in var_group:
                for pair in zip(*[iter(entry[2])]*2):
                    csv_output.writerow([key[0], key[1], entry[1], up, pair[1]])
                    up = int(pair[1]) + 1

f_output.close()

使用您提供的数据,这会产生以下输出:

A_ID,B_ID,Var,LO,UP
103,321,PV,0,402
103,321,停留,40,250
103,321,居住,251,780
103,321,赛斯,75,350
103,321,赛斯,351,850
103,321,Elap,5,35
103,503,PV,192,225
103,503,PV,226,608
103,503,停留,80,125
103,503,停留,126,585
103,503,埃拉普,100,225
103,503,埃拉普,226,408
106,264,PV,104,258
106,264,PV,259,408
106,264,停留,192,525
106,264,赛斯,92,225
106,264,赛斯,226,608
106,264,埃拉普,102,325
107,197,PV,6,32
107,197,PV,33,258
107,197,居住,324,492
107,197,居住,493,614
107,197,赛斯,24,92
107,197,埃拉普,24,92
107,197,Elap,93,214

要处理文件夹中的所有 csv 文件,您可以在脚本顶部添加以下内容:

import os
import glob

csv_files = [(index, file, os.path.splitext(file)[0]) for index, file in enumerate(glob.glob('*.csv'))]

您还应该更改输出文件的位置,否则它将在下次运行脚本时被读取。

使用 Python 2.6.6 进行测试(我相信这是 OP 正在使用的)

【讨论】:

  • 埃文斯,非常棒。它在这里也工作得很好。我发现一个简单但最复杂的工作是将 +1 添加到前一个 UP 值中,然后将其用作下一行中相同 A_ID、B_ID、Var 的下一个 LO 值,如 finalfile.csv 中的第 2 行所示.这个任务有什么pythonic方法吗?
  • 埃文斯,谢谢。我在以下网址中添加了原始数据。请您看一下文件。目前它显示一个简单的错误,如下 Traceback(最近一次调用最后一次):文件“dataForTable1Final.py”,第 26 行,在 up = var_group[0][2][0] IndexError: list index out of range
  • Dwell 数据:0bin.net/paste/… Elapsed 数据:0bin.net/paste/… PV 数据:0bin.net/paste/…
  • PV中有些行没有数据。它现在跳过这些。
  • 是的,有些记录在第 3 列没有数据,即在第一个 'lower' 列。它仅包含第一列和第二列中的数据。所以,我需要删除第三列(下)中为空的记录。请看一下这个。如果可能的话,想使用循环来读取和操作所有包含“*.csv”扩展名的文件。在执行程序之前,我会在文件上添加 * 星号。
【解决方案3】:

这些操作有一个标准库模块 https://docs.python.org/2/library/csv.html#module-csv

无论如何都不是一个完整的答案,但您的完整实施几乎肯定会从那里开始。上面的 python 文档包含几个可以帮助您入门的工作示例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-19
    • 2013-07-25
    • 1970-01-01
    • 1970-01-01
    • 2017-06-22
    • 1970-01-01
    • 2020-01-04
    相关资源
    最近更新 更多