我正在尝试将一些随机数据添加到文本文件中,我很成功,但我遇到了标题行的问题。我想添加标题行一次然后每次运行我的脚本时,它应该只将数据添加到文件中并忽略标题行(如果存在)。我试过这样的事情,但我失败了。我尝试在SO python csv, writing headers only once中查看此示例代码,但无法正确实现。 如果有人帮我纠正我的代码。我会很感激的。
Creating:
它插入数据但不添加任何标题行。我想在第一次运行脚本时包含标题,下次当我多次运行脚本时,它应该只添加数据而不是标题行。非常感谢任何想法或帮助。
答案 0 :(得分:4)
埃文斯先生方法的一个稍微简单的替代方法是使用以下测试代替存在的测试:
fileEmpty = os.stat('collection1.dat').st_size == 0
这消除了寻求等的需要。
编辑:完整代码:
import random
import csv
import os.path
from time import gmtime, strftime
filename = '/home/robdata/collection1.dat'
fileEmpty = os.stat(filename).st_size == 0
v = random.randint(0, 100)
with open(filename, "a") as csvfile:
headers = ['DATE', 'value']
writer = csv.DictWriter(csvfile, delimiter=',', lineterminator='\n',fieldnames=headers)
if fileEmpty:
writer.writeheader() # file doesn't exist yet, write a header
writer.writerow({'DATE': strftime("%Y-%m-%d %H:%M:%S", gmtime()), 'value': v})
答案 1 :(得分:3)
不是测试文件是否存在,而是通过寻找到最后并询问文件位置来检查是否具有零长度。当文件为空但仍然存在时,这也会写出案例的标题。
import random
import csv
from time import gmtime, strftime
headers = ['DATE', 'value']
v = random.randint(0, 100)
with open('collection1.dat', 'ab') as f_output:
csv_output = csv.DictWriter(f_output, fieldnames=headers)
f_output.seek(0, 2)
if f_output.tell() == 0:
csv_output.writeheader()
csv_output.writerow({'DATE': strftime("%Y-%m-%d %H:%M:%S", gmtime()), 'value': v})
然后仅在文件为空时才使用 writeheader()
来编写标头。
此外,使用csv
库时,应始终以二进制模式打开文件,例如ab
答案 2 :(得分:1)
从Python CSV模块的文档中,writeheader
只能与DictWriter一起使用。
[{https://docs.python.org/2/library/csv.html#csv.DictWriter.writeheader][Documentation的写作者]
因此,代码不应该使用writeheader
。
你可以试试这个。
if not file_exists:
writer.writerow(headers)
else:
writer.writerow([strftime("%Y-%m-%d %H:%M:%S", gmtime()), v, w, z])
答案 3 :(得分:1)
在我们发布回答时,您似乎编辑了自己的问题。请添加任何更改作为编辑或提及您更改的内容。无论如何,虽然字典字段不同,但概念是相同的。
在dictwriter
之上,您需要将行数据作为值传递给每列的dict键。
我为延迟5秒的5次写入添加了一个循环作为样本 见下文。
工作代码:
import random
import csv
import os.path
from time import gmtime, strftime, sleep
filename = 'collection1.csv'
file_exists = os.path.isfile(filename)
v = random.randint(0, 100)
w = random.randint(0, 100)
z = random.randint(0, 100)
with open(filename, "a") as csvfile:
for i in range(5):
headers = ['timestamp','val1', 'val2', 'val3']
writer = csv.DictWriter(csvfile, delimiter=',', lineterminator='\n',fieldnames=headers)
if not file_exists:
writer.writeheader()
else:
mytime = strftime("%Y-%m-%d %H:%M:%S", gmtime())
writer.writerow({'timestamp':mytime, 'val1': v,'val2': w, 'val3':z})
sleep(5)
collection1.csv
timestamp,val1,val2,val3
2017-03-23 14:07:20,83,60,11
2017-03-23 14:07:25,83,60,11
2017-03-23 14:07:30,83,60,11
2017-03-23 14:07:47,55,44,88
2017-03-23 14:07:52,55,44,88
2017-03-23 14:07:57,55,44,88
2017-03-23 14:08:02,55,44,88
2017-03-23 14:08:07,55,44,88
答案 4 :(得分:0)
如果要将pandas DataFrame 附加到一个csv文件中,并且只想在首次写出时保留标题,这对我有用,比以前的解决方案简单得多:
start = 100
with open('path_to_your_csv', "r",encoding = 'UTF-8') as myfile:
reader = csv.DictReader(myfile)
for i,line in itertools.islice(enumerate(reader) , start, 105): # iterate through row 100:105
df # this is the data frame you want to export
if i == start:
df.iloc[0:0].to_csv(recent,sep = ",") # keep only header if this is the first you export
df.to_csv(total,sep = ",",header =False)
del df