Невозможно записать значения из списка в CSV Python
Я пытаюсь записать некоторые данные из моей базы данных InfluxDB в CSV. Несмотря на то, что infxdb-cli позволяет мне экспортировать данные в csv, мне не разрешено самостоятельно запускать cli на сервере. Я использую пакет Python Influx-DB для запроса базы данных.
Теперь вот код, который я использую:
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 ....
.
.
.
Я попробовал несколько решений, которые я нашел, но ни одно из них не помогло. Кто-нибудь знает, что идет не так?
редактировать
Я также хотел "Natural_sort" заголовки, так как имеет смысл иметь его в этом формате. Для этого я сослался на этот ответ на SO. Но чтобы сделать это, мне нужно было проигнорировать первый элемент, который называется "время", и отсортировать только заголовки "значения", которые я использовал, используя этот
Последнее, что мне нужно, - это вычислить смещение текста, так как некоторые измерения имеют "val" в качестве имени поля, а некоторые имеют "value". Смещение равно 3 и 5 соответственно, которые я буду использовать в фрагменте естественной сортировки. Для этого я сослался на это. Я наконец-то закончил тем, что данные выглядят как
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 за ответ
3 ответа
Вы должны сделать это ниже. Этот способ имеет проблему случайного порядка записи данных в 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])
Поскольку у вас есть не только повторяемые значения, но и словари пар ключ: значение, вы должны использовать csv.DictWriter
вместо csv.writer
,
Используйте 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)