重新组织CSV以便date不是列标题
我正在尝试重新组织一个Excel表(或csv),以便date不再是列标题。 我正在使用Python的有限的知识来尝试这样做,但由于不知道从哪里开始,我可以使用一些帮助。
在每一个date之下,logging了当天发生在特定地点的事情。 空值可以被跳过。 有些单元格包含一个“ – ”,可以转换为0.我想列date和列表示一天的数字阅读。 如果当天受到监控,地名就是一个新的行。
例子(以这种方式开始的人smh):
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.
有数百行(地方)和列(date)已经得到BPD(这是正确的1772列!)。
你想要做的是正常化为表格。
通常这样做的方法是:对于denormal表中的每一行,将行插入到每个非正规列的普通表中。
你这样做的方式特别取决于你如何处理表格。 例如,如果您在Python 3.x中使用csv
模块,并且使用Excel默认的方言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
/ xlwt
, XlsxReader
/ XlsxWriter
, win32com
的Excel脚本等,细节将会有所不同,但基本思想是一样的:遍历行,然后迭代date列,根据行的名称,列标题的date和行的值,为每个行生成一个新行。
你应该能够弄清楚如何跳过空值,将"--"
转换为0
等。
下面的代码是非常明显的,即使你刚开始使用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')
下面的代码将标准化为您所描述的格式的表格csv,并输出一个新的csv文件,每个(Place,Date)对具有logging的行。 它也会将任何列为“ – ”的logging更改为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)