【问题标题】:Unable to write values from list to csv python无法将列表中的值写入csv python
【发布时间】:2018-05-03 08:32:28
【问题描述】:

我正在尝试将一些数据从我的 InfluxDB 数据库写入 csv。虽然 influxdb-cli 允许我将数据导出到 csv,但我不能自己在服务器上运行 cli。我正在使用influx-db python 包查询数据库。

现在,这是我正在使用的代码:

import csv
from influxdb import InfluxDBClient

USER='root'
PASSWORD='root'
DBNAME='sensordata'
HOST='localhost'
PORT=8086

client = InfluxDBClient(HOST,PORT,USER,PASSWORD,DBNAME)
query="select * from home where time > '2017-11-15 14:55:00' AND time <= '2017-11-15 14:55:05' tz('Asia/Kolkata')"
result = client.query(query,epoch='ns')
exported_data = list(result.get_points())
with open("output.csv", "a", newline='') as fp:
    writer = csv.writer(fp, dialect='excel')
    for line in exported_data:
        print(line)
        writer.writerow(line)

问题是,当我打印这些行时,我会同时得到键和值,如下所示:

{'time': 1510737900336919297, 'value1': 18.84, 'value10': 19.83, 'value2': 18.56, 'value3': 12.61, 'value4': 17.57, 'value5': 16.6, 'value6': 16.81, 'value7': 12.84, 'value8': 11.54, 'value9': 14.26}
{'time': 1510737901370333995, 'value1': 11.32, 'value10': 12.98, 'value2': 12.34, 'value3': 12.22, 'value4': 11.08, 'value5': 12.07, 'value6': 17.62, 'value7': 14.68, 'value8': 16.87, 'value9': 11.4}
{'time': 1510737902403461281, 'value1': 12.37, 'value10': 16.18, 'value2': 18.83, 'value3': 14.59, 'value4': 11.79, 'value5': 18.52, 'value6': 11.25, 'value7': 17.28, 'value8': 10.54, 'value9': 19.1}
{'time': 1510737903436997966, 'value1': 13, 'value10': 12.04, 'value2': 10.02, 'value3': 14.28, 'value4': 14.51, 'value5': 17.3, 'value6': 16.14, 'value7': 15.04, 'value8': 13.16, 'value9': 10.47}
{'time': 1510737904470366806, 'value1': 16.2, 'value10': 10.83, 'value2': 12.64, 'value3': 13.51, 'value4': 13.74, 'value5': 11.52, 'value6': 13.42, 'value7': 13.14, 'value8': 16.6, 'value9': 11.24}

但是,csv 文件只包含这样的键:

time,value1,value10,value2,value3,value4,value5,value6,value7,value8,value9
time,value1,value10,value2,value3,value4,value5,value6,value7,value8,value9
time,value1,value10,value2,value3,value4,value5,value6,value7,value8,value9
time,value1,value10,value2,value3,value4,value5,value6,value7,value8,value9
time,value1,value10,value2,value3,value4,value5,value6,value7,value8,value9

我在这里做错了什么?

另外,我是否可以将 csv 格式设置为:

time_heading, value1_heading, value2_heading ....
time_value, value1_value, value2_value ....
time_value, value1_value, value2_value ....
time_value, value1_value, value2_value ....
.
.
.

我确实尝试了一些我在 Google 上搜索过的解决方案,但没有一个有帮助。有谁知道怎么回事?

编辑

我还想对标头进行“自然排序”,因为采用这种格式是有意义的。为此,我参考了this SO 上的答案。但是,要做到这一点,我需要忽略第一项是“时间”并仅对我使用 this 所做的“值”标题进行排序。

我需要做的最后一件事是计算文本的偏移量,因为一些测量以“val”作为字段名称,而一些测量具有“值”。偏移量分别为 3 和 5,我将在自然排序 sn-p 中使用它们。为此,我参考了this。我最终得到的数据看起来像

time,value1,value2,value3,....value10 而不是time,value1,value10,value2,value3,...value9,这正是我想要的。

这是最终代码的样子:

import csv
from influxdb import InfluxDBClient

USER = 'root'
PASSWORD = 'root'
DB_NAME = 'sensordata'
HOST = 'localhost'
PORT = 8086

client = InfluxDBClient(HOST, PORT, USER, PASSWORD, DB_NAME)
query = "select * from home where time > '2017-11-15 14:55:00' AND time <= '2017-11-15 14:55:05' tz('Asia/Kolkata')"
result = client.query(query, epoch='ns')
exported_data = list(result.get_points())
header_list = list(exported_data[0].keys())

with open("output.csv", "w", newline='') as fp:
    writer = csv.writer(fp, dialect='excel')
    # print(header_list[1:])
    value_header = header_list[1]
    offset = sum(c.isalpha() for c in value_header)
    # print(offset)
    header_list[1:] = sorted(header_list[1:], key=lambda x: int(x[offset:]))
    # print(header_list)
    writer.writerow(header_list)
    for line in exported_data:
        # print(line)
        writer.writerow([line[kn] for kn in header_list])

感谢@be_good_do_good 的回答

【问题讨论】:

    标签: python csv influxdb influxdb-python


    【解决方案1】:

    您需要按照以下方式进行操作。这种方式存在csv中写入数据顺序随机的问题:

    with open("output.csv", "a", newline='') as fp:
        writer = csv.writer(fp, dialect='excel')
        writer.writerow(exported_data[0].keys())
        for line in exported_data:
            print(line)
            writer.writerow(line.values())
    

    你做的一切都是正确的,但是当你传递一个字典时,键被当作list,所以你需要指定需要写入csv的内容-line.values()

    如果您对键的顺序感兴趣,请按以下方式进行:

    with open("output.csv", "a", newline='') as fp:
        writer = csv.writer(fp, dialect='excel')
        header_list = ['time,value1,value10,value2,value3,value4,value5,value6,value7,value8,value9']
        writer.writerow(header_list)
        for line in exported_data:
            print(line)
            writer.writerow([line[kn] for kn in header_list])
    

    【讨论】:

    • line.values() 的顺序是任意的,因此会产生垃圾结果。
    • 但它会像键一样随意,不是吗?
    • 键没有顺序。 line.values() 可能会针对在 for 循环的每次迭代中表示的键为您提供不同的排序。
    • 我仔细检查了它。 line.values 以与 line.keys() 相同的顺序打印
    • 更改了答案,使标题现在与值匹配
    【解决方案2】:

    由于您不仅有可迭代的值,还有键:值对的字典,因此您应该使用 csv.DictWriter 而不是 csv.writer

    【讨论】:

    • 如您所见,我在这里使用了一个列表:exported_data = list(result.get_points()) DictWriter 在这种情况下会有所帮助吗?我假设它不会因为它的命名方式,但无论如何我都会试一试。
    • @karanRajpal 重点是您的list 包含dicts。这正是DictWriter 的用途。 list 中的每个 dict 都被 DictWriter 视为一行。
    【解决方案3】:

    对字典使用 csv.DictWriter(),对列表使用 csv.writer()。

    with open('output.csv','a') as file:
        writer = csv.DictWriter(file, exported_data[0].keys())
        writer.writeheader()
        writer.writerows(exported_data)
    

    【讨论】:

    • 我收到此错误File "/usr/lib/python3.6/csv.py", line 143, in writeheader header = dict(zip(self.fieldnames, self.fieldnames)) TypeError: zip argument #1 must support iteration 从我可以通过一点搜索收集到的信息来看,只有当我的“exported_data”是字典时,dict writer 才会有用,对吗?在这种情况下,我使用的是您可以在此处看到的列表:exported_data = list(result.get_points()) 您建议我在这里做什么?
    猜你喜欢
    • 1970-01-01
    • 2013-07-16
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    • 2018-11-22
    • 1970-01-01
    • 2014-09-21
    相关资源
    最近更新 更多