Автор: Шабанов Павел
E-mail: meteomail@yandex.ru
Иногда необходимые данные доступны только в формате xls или xlsx. Научимся "заливать" их в python.
Исходные данные скачиваем с сайта Earth Policy Institute (http://www.earth-policy.org/data_center/C23) файл Average Global Temperature, 1880-2013 в формате XLS. На 04/04/2014 вирусы в этом файле обнаружены не были.
Для чтения будем использовать модуль xlrd (http://www.python-excel.org/) для чтения файлов формата xls, xlsx (MS Excel 2007 и выше). Логика использования этого модуля состоит в последовательном переходе с одного уровня на другой, более низкий: Лист -> Строка/Столбец -> Ячейка.
import numpy as np
import xlrd
path = u'indicator8_2014_1.xlsx' # имя и путь к файлу
wb = xlrd.open_workbook(path) # открываем файл и передаём его как объект в wb
''' Методы sheet_names показывает список имён доступных для работы листов файла'''
sheets = wb.sheet_names()
print 'MS Excel sheets:', sheets
print type(sheets), len(sheets)
''' Передаём первый (и едиственный в данном случае) лист как объект sh '''
sh = wb.sheet_by_name(sheets[0])
MS Excel sheets: [u'Temp'] <type 'list'> 1
Таким образом, мы узнали, что в файле всего 1 нормальный лист с данными и перешли на этот лист для дальнейшей работы. Перейдём к столбцам и стокам: узнаем сколько их доступно.
print 'Sheet name:',sh.name # выведем имя текущего листа
print 'Number of rows:',sh.nrows, 'Number of cells in choosed column:',len(sh.col(0)) # число строк разными способами
print 'Number of columns:', sh.ncols, 'Number of cells in choosed row:', len(sh.row(0)) # число столбцов разными способами
Sheet name: Temp Number of rows: 141 Number of cells in choosed column: 141 Number of columns: 2 Number of cells in choosed row: 2
''' Передаём колонки в виде списков year и temp '''
year = sh.col_values(0) # Важно передать именно values. Иначе* будет передан список из особого класса ячеек Cells
temp = sh.col_values(1)
# * ИНАЧЕ
cell = sh.col(0)[0]
print 'Type of cell', type(cell)
print 'XL_CELL_TEXT 1 (Unicode string):', cell.ctype
print 'Cell value:', cell.value
cell = sh.col(0)[5]
print 'XL_CELL_NUMBER 2 (float):', cell.ctype
print 'Cell value:', cell.value
print '----------------------------------------'
print year
print temp
Type of cell <class 'xlrd.sheet.Cell'> XL_CELL_TEXT 1 (Unicode string): 1 Cell value: Average Global Temperature, 1880-2013 XL_CELL_NUMBER 2 (float): 2 Cell value: 1880.0 ---------------------------------------- [u'Average Global Temperature, 1880-2013', '', u'Year', '', '', 1880.0, 1881.0, 1882.0, 1883.0, 1884.0, 1885.0, 1886.0, 1887.0, 1888.0, 1889.0, 1890.0, 1891.0, 1892.0, 1893.0, 1894.0, 1895.0, 1896.0, 1897.0, 1898.0, 1899.0, 1900.0, 1901.0, 1902.0, 1903.0, 1904.0, 1905.0, 1906.0, 1907.0, 1908.0, 1909.0, 1910.0, 1911.0, 1912.0, 1913.0, 1914.0, 1915.0, 1916.0, 1917.0, 1918.0, 1919.0, 1920.0, 1921.0, 1922.0, 1923.0, 1924.0, 1925.0, 1926.0, 1927.0, 1928.0, 1929.0, 1930.0, 1931.0, 1932.0, 1933.0, 1934.0, 1935.0, 1936.0, 1937.0, 1938.0, 1939.0, 1940.0, 1941.0, 1942.0, 1943.0, 1944.0, 1945.0, 1946.0, 1947.0, 1948.0, 1949.0, 1950.0, 1951.0, 1952.0, 1953.0, 1954.0, 1955.0, 1956.0, 1957.0, 1958.0, 1959.0, 1960.0, 1961.0, 1962.0, 1963.0, 1964.0, 1965.0, 1966.0, 1967.0, 1968.0, 1969.0, 1970.0, 1971.0, 1972.0, 1973.0, 1974.0, 1975.0, 1976.0, 1977.0, 1978.0, 1979.0, 1980.0, 1981.0, 1982.0, 1983.0, 1984.0, 1985.0, 1986.0, 1987.0, 1988.0, 1989.0, 1990.0, 1991.0, 1992.0, 1993.0, 1994.0, 1995.0, 1996.0, 1997.0, 1998.0, 1999.0, 2000.0, 2001.0, 2002.0, 2003.0, 2004.0, 2005.0, 2006.0, 2007.0, 2008.0, 2009.0, 2010.0, 2011.0, 2012.0, 2013.0, '', u'Source: Compiled by Earth Policy Institute from National Aeronautics and Space Administration, Goddard Institute for Space Studies, \u201cGlobal Land-Ocean Temperature Index in 0.01 Degrees Celsius,\u201d at data.giss.nasa.gov/gistemp/tabledata_v3/GLB.Ts+dSST.txt, updated 21 January 2014.'] ['', '', u'Temperature', u'Degrees Fahrenheit', '', 56.822, 56.984, 56.912000000000006, 56.876000000000005, 56.732, 56.75, 56.768, 56.642, 56.858000000000004, 57.038000000000004, 56.624, 56.732, 56.642, 56.57, 56.624, 56.75, 56.876000000000005, 56.876000000000005, 56.642, 56.84, 56.93, 56.822, 56.660000000000004, 56.552, 56.408, 56.660000000000004, 56.732, 56.444, 56.426, 56.354000000000006, 56.372, 56.408, 56.462, 56.498000000000005, 56.786, 56.912000000000006, 56.552, 56.408, 56.642, 56.678000000000004, 56.714000000000006, 56.84, 56.678000000000004, 56.75, 56.768, 56.822, 57.038000000000004, 56.876000000000005, 56.912000000000006, 56.642, 56.984, 57.074000000000005, 57.002, 56.75, 57.038000000000004, 56.93, 57.02, 57.254000000000005, 57.308, 57.218, 57.326, 57.344, 57.290000000000006, 57.308, 57.452000000000005, 57.2, 57.056000000000004, 57.128, 57.02, 57.002, 56.858000000000004, 57.092000000000006, 57.236000000000004, 57.362, 57.002, 56.984, 56.876000000000005, 57.272000000000006, 57.272000000000006, 57.236000000000004, 57.128, 57.290000000000006, 57.272000000000006, 57.326, 56.84, 57.02, 57.128, 57.182, 57.11, 57.308, 57.272000000000006, 57.074000000000005, 57.236000000000004, 57.488, 57.074000000000005, 57.182, 56.984, 57.470000000000006, 57.308, 57.416000000000004, 57.614000000000004, 57.704, 57.362, 57.686, 57.416000000000004, 57.344, 57.470000000000006, 57.722, 57.830000000000005, 57.632000000000005, 57.902, 57.884, 57.542, 57.578, 57.722, 57.974000000000004, 57.794000000000004, 58.028000000000006, 58.316, 57.938, 57.938, 58.154, 58.316, 58.298, 58.136, 58.388000000000005, 58.28, 58.334, 58.082, 58.28, 58.406000000000006, 58.190000000000005, 58.244, 58.298, '', '']
Мы присвоили спискам первый и второй столбцы файла. Как видно, мы прочитали лишние ячейки - "шапку" и "комментарии". Считаем только числовую информацию явно указав диапазон необходимых нам строк.
row1 = 6
row2 = 139
year = sh.col_values(0,row1,row2)
temp = sh.col_values(1,row1,row2)
Нарисуем результат.
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(year,temp,'k-')
ax.set_xlabel('Source: NASA GIS')
ax.set_ylabel('Degrees Fahrenheit')
ax.set_title('Average Global Temperature, 1880-2013')
ax.grid(axis='y', color='k', linestyle='-', linewidth=0.5)
plt.show()
Правда, похоже на рисунок со второго листа, который мы не обнаружили при поиске доступных листов? =)