Сделайте график из CSV-файла с тысячами записей в Python

У меня есть этот код в Python, который работает.

from matplotlib import style
from matplotlib import pylab as plt
import numpy as np

style.use('ggplot')

filename='results.csv'
value=[]
date=[]

import csv
with open(filename, 'r') as csvfile:
    csvreader = csv.reader(csvfile)
    for row in csvreader:
        if len(row) ==2:
            value.append(row[0])
            date.append(row[1])

value=np.array(value)

import datetime
for ii in range(len(date)):
    date[ii]=datetime.datetime.strptime(date[ii], '%a %b %d')
plt.ylim(2, -2) 
plt.plot(date, value)

plt.show()

И файл.csv (почти 18000 записей):

[0.0]   Thu Mar 15
[0.0]   Thu Mar 15
[0.0]   Thu Mar 15
[0.0]   Thu Mar 15
[-0.05] Thu Mar 15
[0.0]   Thu Mar 15
[0.0]   Thu Mar 15
    ....

Итак, когда я запускаю код, я получаю такой результат: введите описание изображения здесь

Дело в том, что я хочу, чтобы значения по оси Y от [-2,2] в порядке возрастания, чтобы наблюдать маршрут сюжетной линии. Является ли мое обоснование для визуализации такого CSV неправильно или я пропустил что-то важное? Буду признателен за любую помощь.

2 ответа

У ваших ценностей есть окружающие скобки, не знаю почему. Когда я пытаюсь этот код с numpy 1.14.1 и matplotlib 2.0.0, он выдает исключение, что вы не можете конвертировать [0.0] в float.

После попытки этого кода в Anaconda (matplotlib 2.1.2 и numpy 1.14.0) код работает. Однако y-Scale отображается неправильно. Я думаю, что может быть ошибка в одном из этих пакетов.

Прежде всего, вы должны преобразовать значение [0.0] с помощью eval (из пакета ast) в список, а затем взять первый элемент списка. Так что просто измените ваше значение.

import ast
.
.
value.append(ast.literal_eval(row[0])[0])

После этого вы настраиваете отображение matplotlib от 2 до -2. Вы должны установить ylim так:

plt.ylim(-0.05, 2)

Итак, полный пример

from matplotlib import style
from matplotlib import pylab as plt
import numpy as np
import ast

style.use('ggplot')

filename='results.csv'
value=[]
date=[]

import csv
with open(filename, 'r') as csvfile:
    csvreader = csv.reader(csvfile, delimiter='\t')
    for row in csvreader:
        if len(row) ==2:
            value.append(ast.literal_eval(row[0])[0])
            date.append(row[1])

value=np.array(value)

import datetime
for ii in range(len(date)):
    date[ii]=datetime.datetime.strptime(date[ii], '%a %b %d')
plt.ylim(-0.05, 2) 
plt.plot(date, value)
print(value)

plt.show()

Более того, есть гораздо лучшие решения для вашей задачи. Подумайте об использовании панд. Я предположил, что вам нужен 2018 год.

from matplotlib import style
from matplotlib import pylab as plt
from dateutil.parser import parse
import datetime
import pandas as pd
import ast

style.use('ggplot')

filename = 'results.csv'
df = pd.read_csv('results.csv', sep='\t')
df.columns = ['value', 'date']
# Convert to datetime
df.date = df.date.apply(lambda x:
    parse(x, default=datetime.datetime(2018, 1, 1)))
# Unpack your list elements
df.value = df.value.apply(lambda x: ast.literal_eval(x)[0])

plt.plot(df.date, df.value)
plt.ylim(-0.05, 2)

plt.show()

Как уже упоминалось в комментариях, использование eval является проблемой безопасности. Лучше использовать literal_eval из пакета ast.

Использование панд намного упрощает вещи. Вы можете непосредственно снять скобки с данных при чтении файла.

u = u"""[0.0]\tThu Mar 14
[0.0]\tThu Mar 15
[0.0]\tThu Mar 16
[0.0]\tThu Mar 17
[-0.05]\tThu Mar 18
[2.0]\tThu Mar 19
[0.0]\tThu Mar 20"""

import io
import pandas as pd
import matplotlib.pyplot as plt
import datetime

parse_date = lambda x: datetime.datetime.strptime(x, "%a %b %d")
parse_vals = lambda x: float(x.strip("[]"))
df = pd.read_csv(io.StringIO(u), sep="\t",header=None,names=["val", "date"],
                 converters={0:parse_vals,1:parse_date} )

df.set_index("date").plot()

plt.show()

введите описание изображения здесь

Другие вопросы по тегам