【问题标题】:Reorganize a CSV so Dates are not column Headers重新组织 CSV,使日期不是列标题
【发布时间】:2014-10-23 19:52:40
【问题描述】:

我正在尝试重新组织 Excel 表(或 csv),以便日期不再是列标题。我正在使用有限的 python 知识来尝试执行此操作,但由于不知道从哪里开始,我可以使用一些帮助。

在每个日期下方是特定地点当天发生的事情的记录。可以跳过空值。某些单元格包含“--”并且可以转换为 0。我想为日期创建一列,并为当天的数字读数创建一列。如果那天被监控,则该地名是一个新行。

示例(以这种方式开始的人):

Name,7/1/2009,7/2/2009,7/3/2009,7/4/2009..... (and so on to the present)
Place A,,5,3,
Place B,0,,23,--
Place C,1,2,,35

我想要的是:

Name, Date, Reading
Place A, 7/2/2009, 5
Place A, 7/3/2009, 3
Place B, 7/1/2009, 0
Place B, 7/4/2009, 0   <--- Even though this is a dash originally it can be converted to a 0 to keep the number an int.  

有数百行(地点)和列(日期)已到达 BPD(没错 1772 列!)。

【问题讨论】:

  • 您知道如何使用csv 模块,或处理.xls 文件或编写Excel 脚本的不同方法之一吗?你想用哪一个? (它们在这里都可以正常工作。)

标签: python excel csv


【解决方案1】:

您要做的是规范化为表格。

您通常执行此操作的方式是:对于非正规表中的每一行,您将行插入到正常表中的每个非正规列。

您执行此操作的方式尤其取决于您处理表格的方式。例如,如果您在 Python 3.x 中使用csv 模块和 Excel-default-dialect CSV 文件,它将如下所示:

with open('old.csv') as oldcsv, open('new.csv', 'w') as newcsv:
    r, w = csv.reader(oldcsv), csv.writer(newcsv)
    header = next(r)
    w.writerow(['Name', 'Date', 'Reading'])
    for row in r:
        for colname, colval in zip(header[1:], row[1:]):
            w.writerow([row[0], colname, colval])

如果你想使用,例如xlrd/xlwtXlsxReader/XlsxWriterwin32com Excel 等脚本,细节会有所不同,但基本思想会是相同:遍历行,然后遍历日期列,根据行中的名称、列标题中的日期和行中的值为每一列生成一个新行。

您应该能够从这里弄清楚如何跳过空值、将"--" 转换为0 等等。

【讨论】:

  • 谢谢!通过对我的情况进行一些独特的更改,我能够让它发挥作用。我相信下面的两个 cmets 会很好用。谢谢大家!
【解决方案2】:

即使您只是从python 开始,下面的代码也很容易解释:

enumerate是索引的迭代器,可迭代的值

>>> content = """Name,7/1/2009,7/2/2009,7/3/2009,7/4/2009
... Place A,,5,3,
... Place B,0,,23,--
... Place C,1,2,,35"""
>>> 
>>> lines = [line.split(',') for line in content.split('\n')]
>>> 
>>> for line in lines:
...   if 'Name' not in line[0]:
...     for count, date in enumerate(lines[0]):
...       if count >= 1:
...         if not line[count] or line[count] == '--':
...           line[count] = 0
...         # write (line[0], date, line[count]) to a file or print it:
...         print (line[0], date, line[count])
... 
('Place A', '7/1/2009', 0)
('Place A', '7/2/2009', '5')
('Place A', '7/3/2009', '3')
('Place A', '7/4/2009', 0)
('Place B', '7/1/2009', '0')
('Place B', '7/2/2009', 0)
('Place B', '7/3/2009', '23')
('Place B', '7/4/2009', 0)
('Place C', '7/1/2009', '1')
('Place C', '7/2/2009', '2')
('Place C', '7/3/2009', 0)
('Place C', '7/4/2009', '35')

【讨论】:

    【解决方案3】:

    以下代码会将您描述的格式的 csv 标准化为表格,并输出一个新的 csv 文件,其中包含每个 (Place,Date) 对具有记录的行。它还会将任何列为“--”的记录更改为 0。

    oldlist = []
    newlist = ['Name,Date,Reading'] 
    
    with open('path_to_csv.csv') as oldcsv, open('newcsv.csv', 'w') as newcsv:
        for line in oldcsv:
            line = line.strip('\n')
            oldlist.append(line.split(','))
    
        for (i,row) in enumerate(oldlist[1:]):
            for (j, column) in enumerate(row[1:]):
                if column != '':
                    newrow = []
                    newrow.append(row[0]) #Adds place name to each newlist row.
                    newrow.append(oldlist[0][j+1]) #Adds date to each newlist row.
                    if column == '--':
                        newrow.append('0')
                    else:
                        newrow.append(column) #Adds reading to each newlist row.
                    newlist.append(",".join(newrow))
    
        for line in newlist:    
            newcsv.write("%s\n" % line)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-20
      • 2011-11-14
      • 1970-01-01
      • 2014-08-06
      • 2022-11-12
      • 2012-11-26
      • 1970-01-01
      • 2021-04-22
      相关资源
      最近更新 更多