Упрощенное построение строк/столбцов CSV на Python

У меня есть файл csv, который я пытаюсь прочитать. Первая строка на листе excel/csv — это заголовки столбцов «Январь | Февраль | Март ...» и т. Д. Затем под каждым заголовком столбца находятся данные с плавающей запятой. У меня есть следующий код:

filename ='Data.csv'
with open(filename) as f:
csvreader = csv.reader(f)
header_row = next(csvreader)
Jan, Feb = [], [] .... #(and so on)
Mar = []
Apr = []
May = []
Jun = []
Jul = []
Aug = []
Sep = []    
Oct = []
Nov = []
Dec = []
for row in csvreader:
    Jan.append(float(row[1]))
    Feb.append(float(row[2]))
    Mar.append(float(row[3]))
    Apr.append(float(row[4]))
    May.append(float(row[5]))
    Jun.append(float(row[6]))
    Jul.append(float(row[7]))
    Aug.append(float(row[8]))
    Sep.append(float(row[9]))
    Oct.append(float(row[10]))
    Nov.append(float(row[11]))
    Dec.append(float(row[12]))

Как мне сжать этот код, чтобы я мог легко построить гистограмму с месяцами на оси x и данными на оси y?


person Jonathon    schedule 15.09.2017    source источник
comment
Во-первых, вы можете попросить программу чтения csv проанализировать заголовок. DictReader docs.python.org/3/library/csv.html#csv .DictReader может помочь вам с другим.   -  person pvg    schedule 15.09.2017


Ответы (2)


Для меня самый простой способ — использовать библиотеку pandas, поскольку она предоставляет возможности построения графиков прямо из фрейма данных.

import pandas as pd

df = pd.read_csv('Data.csv', sep='|') # or your sep in file
...
df.plot.bar()

Изменить: если у вас есть данные в Excel, нет необходимости указывать sep, как для файла csv. Чтобы прочитать файл Excel, это так же просто, как:

df = pd.read_excel('Data.xlsx', sheetname='name')
df.plot.bar()

http://pandas.pydata.org/pandas-docs/version/0.20/generated/pandas.read_excel.html

Несколько примеров:

df2 = pd.DataFrame(np.random.rand(10, 4), columns=['a', 'b', 'c', 'd'])
df2.plot.bar()

Документация Pandas по гистограмме: https://pandas.pydata.org/pandas-docs/stable/visualization.html#visualization-barplot

person StefanK    schedule 15.09.2017
comment
The best way .. кажется субъективным, почему это лучше, чем использование модуля csv? - person wwii; 15.09.2017
comment
Извините, я отредактировал субъективную часть ..., это потому, что вы используете один пакет для чтения файла, очистки файла и файла графика из интерфейса данных. - person StefanK; 15.09.2017
comment
Я все еще изучаю Python, но пока не фанат панд. Что делает команда sep. Мой файл в Excel, и я использовал | просто чтобы показать, что месяцы находятся в разных столбцах. - person Jonathon; 15.09.2017
comment
@Jonathon sep используется для csv, для чтения excel он вам не нужен. Вместо этого вы используете pd.read_excel() - см. редактирование - person StefanK; 15.09.2017
comment
Ты прав. Панды в этом случае кажутся проще. После чтения данных, как мне изолировать столбцы в переменные x, y, чтобы я мог их построить? - person Jonathon; 15.09.2017
comment
Панды будут делать разумные предположения, Джонатон — что происходит, когда вы звоните df.plot.bar()? - person cphlewis; 15.09.2017

Поддельные данные/установка:

import csv, io
from pprint import pprint
from matplotlib import pyplot as plt

s = '''a, b, c
1, 2, 3
4, 5, 6
7, 8, 9'''
csv_file = io.StringIO(s)
reader = csv.reader(csv_file)

Объекты csv.reader возвращают строки

header = next(reader)
data_rows = list(reader)

>>> pprint(data_rows, width = 20)
[['1', ' 2', ' 3'],
 ['4', ' 5', ' 6'],
 ['7', ' 8', ' 9']]
>>>

Вы можете использовать zip() для переноса данных в столбцы.

data_cols = zip(*data_rows)

>>> pprint(list(data_cols), width = 20)
[('1', '4', '7'),
 (' 2', ' 5', ' 8'),
 (' 3', ' 6', ' 9')]
>>> 

Вы можете связать столбцы с их заголовком, опять же, используя zip, и добавить легенду к графику.

for month, data in zip(header, data_cols):
    plt.plot(data, label = month)
plt.legend()
plt.show()
plt.close()

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


Если вы просто хотите получить данные в контейнер и связать столбцы с их заголовками, поместите их в словарь:

data = {}
for month, column in zip(header, data_cols):
    data[month] = column

>>> data
{'a': ('1', '4', '7'), ' b': (' 2', ' 5', ' 8'), ' c': (' 3', ' 6', ' 9')}
>>>
person wwii    schedule 15.09.2017