├── .gitignore ├── SOMPY.egg-info ├── top_level.txt ├── dependency_links.txt ├── requires.txt ├── PKG-INFO └── SOURCES.txt ├── Capture.PNG ├── figure_1.png ├── figure_2-4.png ├── sompy ├── visualization │ ├── __init__.py │ ├── dotmap.pyc │ ├── hitmap.pyc │ ├── view.pyc │ ├── __init__.pyc │ ├── mapview.pyc │ ├── umatrix.pyc │ ├── histogram.pyc │ ├── __pycache__ │ │ ├── view.cpython-35.pyc │ │ ├── __init__.cpython-35.pyc │ │ ├── bmuhits.cpython-35.pyc │ │ ├── dotmap.cpython-35.pyc │ │ ├── hitmap.cpython-35.pyc │ │ ├── mapview.cpython-35.pyc │ │ ├── umatrix.cpython-35.pyc │ │ └── histogram.cpython-35.pyc │ ├── hitmap.py │ ├── bmuhits.py │ ├── view.py │ ├── histogram.py │ ├── dotmap.py │ ├── umatrix.py │ └── mapview.py ├── __pycache__ │ ├── sompy.cpython-35.pyc │ ├── __init__.cpython-35.pyc │ ├── codebook.cpython-35.pyc │ ├── decorators.cpython-35.pyc │ ├── neighborhood.cpython-35.pyc │ └── normalization.cpython-35.pyc ├── decorators.py ├── __init__.py ├── neighborhood.py ├── normalization.py ├── examples │ ├── main.py │ └── centroids_map.html ├── codebook.py └── sompy.py ├── dist ├── SOMPY-1.0-py2.7.egg └── SOMPY-1.0-py3.5.egg ├── .idea └── vcs.xml ├── .directory ├── setup.py ├── README.md ├── LICENSE └── data ├── eng-climate-summaries-British Columbia-10,2017.csv ├── eng-climate-summaries-British Columbia-12,2017.csv └── eng-climate-summaries-British Columbia-8,2017.csv /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /SOMPY.egg-info/top_level.txt: -------------------------------------------------------------------------------- 1 | sompy 2 | -------------------------------------------------------------------------------- /SOMPY.egg-info/dependency_links.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Capture.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/Capture.PNG -------------------------------------------------------------------------------- /figure_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/figure_1.png -------------------------------------------------------------------------------- /figure_2-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/figure_2-4.png -------------------------------------------------------------------------------- /sompy/visualization/__init__.py: -------------------------------------------------------------------------------- 1 | from . import dotmap, histogram, hitmap, mapview, umatrix 2 | -------------------------------------------------------------------------------- /SOMPY.egg-info/requires.txt: -------------------------------------------------------------------------------- 1 | numexpr >= 2.5 2 | numpy >= 1.7 3 | scikit-learn >= 0.16 4 | scipy >= 0.9 5 | -------------------------------------------------------------------------------- /dist/SOMPY-1.0-py2.7.egg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/dist/SOMPY-1.0-py2.7.egg -------------------------------------------------------------------------------- /dist/SOMPY-1.0-py3.5.egg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/dist/SOMPY-1.0-py3.5.egg -------------------------------------------------------------------------------- /sompy/visualization/dotmap.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/dotmap.pyc -------------------------------------------------------------------------------- /sompy/visualization/hitmap.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/hitmap.pyc -------------------------------------------------------------------------------- /sompy/visualization/view.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/view.pyc -------------------------------------------------------------------------------- /sompy/visualization/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/__init__.pyc -------------------------------------------------------------------------------- /sompy/visualization/mapview.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/mapview.pyc -------------------------------------------------------------------------------- /sompy/visualization/umatrix.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/umatrix.pyc -------------------------------------------------------------------------------- /sompy/visualization/histogram.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/histogram.pyc -------------------------------------------------------------------------------- /sompy/__pycache__/sompy.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/__pycache__/sompy.cpython-35.pyc -------------------------------------------------------------------------------- /sompy/__pycache__/__init__.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/__pycache__/__init__.cpython-35.pyc -------------------------------------------------------------------------------- /sompy/__pycache__/codebook.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/__pycache__/codebook.cpython-35.pyc -------------------------------------------------------------------------------- /sompy/__pycache__/decorators.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/__pycache__/decorators.cpython-35.pyc -------------------------------------------------------------------------------- /sompy/__pycache__/neighborhood.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/__pycache__/neighborhood.cpython-35.pyc -------------------------------------------------------------------------------- /sompy/__pycache__/normalization.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/__pycache__/normalization.cpython-35.pyc -------------------------------------------------------------------------------- /sompy/visualization/__pycache__/view.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/__pycache__/view.cpython-35.pyc -------------------------------------------------------------------------------- /sompy/visualization/__pycache__/__init__.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/__pycache__/__init__.cpython-35.pyc -------------------------------------------------------------------------------- /sompy/visualization/__pycache__/bmuhits.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/__pycache__/bmuhits.cpython-35.pyc -------------------------------------------------------------------------------- /sompy/visualization/__pycache__/dotmap.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/__pycache__/dotmap.cpython-35.pyc -------------------------------------------------------------------------------- /sompy/visualization/__pycache__/hitmap.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/__pycache__/hitmap.cpython-35.pyc -------------------------------------------------------------------------------- /sompy/visualization/__pycache__/mapview.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/__pycache__/mapview.cpython-35.pyc -------------------------------------------------------------------------------- /sompy/visualization/__pycache__/umatrix.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/__pycache__/umatrix.cpython-35.pyc -------------------------------------------------------------------------------- /sompy/visualization/__pycache__/histogram.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhl60492/SOMPY_robust_clustering/HEAD/sompy/visualization/__pycache__/histogram.cpython-35.pyc -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.directory: -------------------------------------------------------------------------------- 1 | [Dolphin] 2 | <<<<<<< HEAD 3 | Timestamp=2017,2,7,17,30,1 4 | Version=3 5 | 6 | [Settings] 7 | HiddenFilesShown=true 8 | ======= 9 | Timestamp=2017,2,8,12,4,41 10 | Version=3 11 | >>>>>>> 503c114584bd9cb91d18379b03a6c9f494d8b4fc 12 | -------------------------------------------------------------------------------- /SOMPY.egg-info/PKG-INFO: -------------------------------------------------------------------------------- 1 | Metadata-Version: 1.0 2 | Name: SOMPY 3 | Version: 1.0 4 | Summary: Self Organizing Maps Package 5 | Home-page: UNKNOWN 6 | Author: Vahid Moosavi and Sebastian Packmann 7 | Author-email: UNKNOWN 8 | License: UNKNOWN 9 | Description: UNKNOWN 10 | Platform: UNKNOWN 11 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | try: 2 | from setuptools import setup, find_packages 3 | except ImportError: 4 | from distutils.core import setup 5 | 6 | 7 | setup( 8 | name="SOMPY", 9 | version="1.0", 10 | description="Self Organizing Maps Package", 11 | author="Vahid Moosavi and Sebastian Packmann", 12 | packages=find_packages(), 13 | install_requires=['numpy >= 1.7', 'scipy >= 0.9', 14 | 'scikit-learn >= 0.16', 'numexpr >= 2.5'] 15 | ) 16 | -------------------------------------------------------------------------------- /SOMPY.egg-info/SOURCES.txt: -------------------------------------------------------------------------------- 1 | setup.py 2 | SOMPY.egg-info/PKG-INFO 3 | SOMPY.egg-info/SOURCES.txt 4 | SOMPY.egg-info/dependency_links.txt 5 | SOMPY.egg-info/requires.txt 6 | SOMPY.egg-info/top_level.txt 7 | sompy/__init__.py 8 | sompy/codebook.py 9 | sompy/decorators.py 10 | sompy/neighborhood.py 11 | sompy/normalization.py 12 | sompy/sompy.py 13 | sompy/visualization/__init__.py 14 | sompy/visualization/bmuhits.py 15 | sompy/visualization/dotmap.py 16 | sompy/visualization/histogram.py 17 | sompy/visualization/hitmap.py 18 | sompy/visualization/mapview.py 19 | sompy/visualization/umatrix.py 20 | sompy/visualization/view.py -------------------------------------------------------------------------------- /sompy/decorators.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from functools import wraps 3 | from time import time 4 | 5 | 6 | def timeit(log_level=logging.INFO, alternative_title=None): 7 | def wrap(f): 8 | @wraps(f) # keeps the f.__name__ outside the wrapper 9 | def wrapped_f(*args, **kwargs): 10 | t0 = time() 11 | result = f(*args, **kwargs) 12 | ts = round(time() - t0, 3) 13 | 14 | title = alternative_title or f.__name__ 15 | logging.getLogger().log( 16 | log_level, " %s took: %f seconds" % (title, ts)) 17 | 18 | return result 19 | 20 | return wrapped_f 21 | return wrap 22 | -------------------------------------------------------------------------------- /sompy/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from logging.config import dictConfig 3 | import matplotlib 4 | 5 | #matplotlib.use('Agg') # Use whatever backend is available 6 | 7 | dictConfig({ 8 | "version": 1, 9 | "disable_existing_loggers": False, 10 | "root": { 11 | "level": "NOTSET", 12 | "handlers": ["console"] 13 | }, 14 | "handlers": { 15 | "console": { 16 | "level": "DEBUG", 17 | "class": "logging.StreamHandler", 18 | "formatter": "basic" 19 | } 20 | }, 21 | "formatters": { 22 | "basic": { 23 | "format": '%(message)s' 24 | } 25 | } 26 | }) 27 | 28 | 29 | 30 | from .sompy import SOMFactory 31 | from .visualization import * 32 | -------------------------------------------------------------------------------- /sompy/visualization/hitmap.py: -------------------------------------------------------------------------------- 1 | from .view import MatplotView 2 | from matplotlib import pyplot as plt 3 | import numpy as np 4 | 5 | 6 | class HitMapView(MatplotView): 7 | 8 | def _set_labels(self, cents, ax, labels): 9 | for i, txt in enumerate(labels): 10 | ax.annotate(txt, (cents[i, 1], cents[i, 0]), size=10, va="center") 11 | 12 | def show(self, som, data=None): 13 | 14 | try: 15 | codebook = getattr(som, 'cluster_labels') 16 | except: 17 | codebook = som.cluster() 18 | 19 | # codebook = getattr(som, 'cluster_labels', som.cluster()) 20 | msz = som.codebook.mapsize 21 | 22 | self.prepare() 23 | ax = self._fig.add_subplot(111) 24 | 25 | if data: 26 | proj = som.project_data(data) 27 | cents = som.bmu_ind_to_xy(proj) 28 | self._set_labels(cents, ax, codebook[proj]) 29 | 30 | else: 31 | cents = som.bmu_ind_to_xy(np.arange(0, msz[0]*msz[1])) 32 | self._set_labels(cents, ax, codebook) 33 | 34 | plt.imshow(codebook.reshape(msz[0], msz[1])[::], alpha=.5) 35 | plt.show() 36 | 37 | return cents 38 | -------------------------------------------------------------------------------- /sompy/neighborhood.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import inspect 3 | import sys 4 | 5 | small = .000000000001 6 | 7 | 8 | class NeighborhoodFactory(object): 9 | 10 | @staticmethod 11 | def build(neighborhood_func): 12 | for name, obj in inspect.getmembers(sys.modules[__name__]): 13 | if inspect.isclass(obj): 14 | if hasattr(obj, 'name') and neighborhood_func == obj.name: 15 | return obj() 16 | else: 17 | raise Exception( 18 | "Unsupported neighborhood function '%s'" % neighborhood_func) 19 | 20 | 21 | class GaussianNeighborhood(object): 22 | 23 | name = 'gaussian' 24 | 25 | @staticmethod 26 | def calculate(distance_matrix, radius, dim): 27 | return np.exp(-1.0*distance_matrix/(2.0*radius**2)).reshape(dim, dim) 28 | 29 | def __call__(self, *args, **kwargs): 30 | return self.calculate(*args) 31 | 32 | 33 | class BubbleNeighborhood(object): 34 | 35 | name = 'bubble' 36 | 37 | @staticmethod 38 | def calculate(distance_matrix, radius, dim): 39 | def l(a, b): 40 | c = np.zeros(b.shape) 41 | c[a-b >= 0] = 1 42 | return c 43 | 44 | return l(radius, 45 | np.sqrt(distance_matrix.flatten())).reshape(dim, dim) + small 46 | 47 | def __call__(self, *args, **kwargs): 48 | return self.calculate(*args) 49 | -------------------------------------------------------------------------------- /sompy/visualization/bmuhits.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | 3 | import matplotlib 4 | import numpy as np 5 | from matplotlib import pyplot as plt 6 | 7 | from .mapview import MapView 8 | 9 | 10 | class BmuHitsView(MapView): 11 | def _set_labels(self, cents, ax, labels, onlyzeros, fontsize): 12 | for i, txt in enumerate(labels): 13 | if onlyzeros == True: 14 | if txt > 0: 15 | txt = "" 16 | ax.annotate(txt, (cents[i, 1] + 0.5, cents[-(i+1), 0] + 0.5), va="center", ha="center", size=fontsize) 17 | 18 | def show(self, som, anotate=True, onlyzeros=False, labelsize=7, cmap="jet", logaritmic = False): 19 | (self.width, self.height, indtoshow, no_row_in_plot, no_col_in_plot, 20 | axis_num) = self._calculate_figure_params(som, 1, 1) 21 | 22 | self.prepare() 23 | ax = plt.gca() 24 | counts = Counter(som._bmu[0]) 25 | counts = [counts.get(x, 0) for x in range(som.codebook.mapsize[0] * som.codebook.mapsize[1])] 26 | mp = np.array(counts).reshape(som.codebook.mapsize[0], 27 | som.codebook.mapsize[1]) 28 | 29 | if not logaritmic: 30 | norm = matplotlib.colors.Normalize( 31 | vmin=0, 32 | vmax=np.max(mp.flatten()), 33 | clip=True) 34 | else: 35 | norm = matplotlib.colors.LogNorm( 36 | vmin=1, 37 | vmax=np.max(mp.flatten())) 38 | 39 | msz = som.codebook.mapsize 40 | 41 | cents = som.bmu_ind_to_xy(np.arange(0, msz[0] * msz[1])) 42 | 43 | if anotate: 44 | self._set_labels(cents, ax, counts, onlyzeros, labelsize) 45 | 46 | 47 | pl = plt.pcolor(mp[::-1], norm=norm, cmap=cmap) 48 | 49 | plt.axis([0, som.codebook.mapsize[1], 0, som.codebook.mapsize[0]]) 50 | ax.set_yticklabels([]) 51 | ax.set_xticklabels([]) 52 | plt.colorbar(pl) 53 | 54 | plt.show() 55 | -------------------------------------------------------------------------------- /sompy/visualization/view.py: -------------------------------------------------------------------------------- 1 | from matplotlib import pyplot as plt 2 | 3 | 4 | class View(object): 5 | def __init__(self, width, height, title, show_axis=True, packed=True, 6 | text_size=2.8, show_text=True, col_size=6, *args, **kwargs): 7 | self.width = width 8 | self.height = height 9 | self.title = title 10 | self.show_axis = show_axis 11 | self.packed = packed 12 | self.text_size = text_size 13 | self.show_text = show_text 14 | self.col_size = col_size 15 | 16 | def prepare(self, *args, **kwargs): 17 | raise NotImplementedError() 18 | 19 | def save(self, filename): 20 | raise NotImplementedError() 21 | 22 | def show(self, *args, **kwrags): 23 | raise NotImplementedError() 24 | 25 | 26 | class MatplotView(View): 27 | 28 | def __init__(self, width, height, title, show_axis=True, packed=True, 29 | text_size=2.8, show_text=True, col_size=6, *args, **kwargs): 30 | super(MatplotView, self).__init__(width, height, title, show_axis, 31 | packed, text_size, show_text, 32 | col_size, *args, **kwargs) 33 | self._fig = None 34 | 35 | def __del__(self): 36 | self._close_fig() 37 | 38 | def _close_fig(self): 39 | if self._fig: 40 | plt.close(self._fig) 41 | 42 | def prepare(self, *args, **kwargs): 43 | self._close_fig() 44 | self._fig = plt.figure(figsize=(self.width, self.height)) 45 | plt.title(self.title) 46 | plt.axis('off') 47 | plt.rc('font', **{'size': self.text_size}) 48 | 49 | def save(self, filename, transparent=False, bbox_inches='tight', dpi=400): 50 | self._fig.savefig(filename, transparent=transparent, dpi=dpi, 51 | bbox_inches=bbox_inches) 52 | 53 | def show(self, *args, **kwrags): 54 | raise NotImplementedError() 55 | -------------------------------------------------------------------------------- /sompy/normalization.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import sys 3 | import inspect 4 | 5 | 6 | class NormalizatorFactory(object): 7 | 8 | @staticmethod 9 | def build(type_name): 10 | for name, obj in inspect.getmembers(sys.modules[__name__]): 11 | if inspect.isclass(obj): 12 | if hasattr(obj, 'name') and type_name == obj.name: 13 | return obj() 14 | else: 15 | raise Exception("Unknown normalization type '%s'" % type_name) 16 | 17 | 18 | class Normalizator(object): 19 | 20 | def normalize(self, data): 21 | raise NotImplementedError() 22 | 23 | def normalize_by(self, raw_data, data): 24 | raise NotImplementedError() 25 | 26 | def denormalize_by(self, raw_data, data): 27 | raise NotImplementedError() 28 | 29 | 30 | class VarianceNormalizator(Normalizator): 31 | 32 | name = 'var' 33 | 34 | def _mean_and_standard_dev(self, data): 35 | return np.mean(data, axis=0), np.std(data, axis=0) 36 | 37 | def normalize(self, data): 38 | me, st = self._mean_and_standard_dev(data) 39 | st[st == 0] = 1 # prevent: when sd = 0, normalized result = NaN 40 | return (data-me)/st 41 | 42 | def normalize_by(self, raw_data, data): 43 | me, st = self._mean_and_standard_dev(raw_data) 44 | st[st == 0] = 1 # prevent: when sd = 0, normalized result = NaN 45 | return (data-me)/st 46 | 47 | def denormalize_by(self, data_by, n_vect): 48 | me, st = self._mean_and_standard_dev(data_by) 49 | return n_vect * st + me 50 | 51 | 52 | class RangeNormalizator(Normalizator): 53 | 54 | name = 'range' 55 | 56 | 57 | class LogNormalizator(Normalizator): 58 | 59 | name = 'log' 60 | 61 | 62 | class LogisticNormalizator(Normalizator): 63 | 64 | name = 'logistic' 65 | 66 | 67 | class HistDNormalizator(Normalizator): 68 | 69 | name = 'histd' 70 | 71 | 72 | class HistCNormalizator(Normalizator): 73 | 74 | name = 'histc' 75 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SOMPY 2 | ----- 3 | A Python Library for Self Organizing Map (SOM) 4 | 5 | As much as possible, the structure of SOM is similar to `somtoolbox` in Matlab. It has the following functionalities: 6 | 7 | 1. Only Batch training, which is faster than online training. It has parallel processing option similar to `sklearn` format and it speeds up the training procedure, but it depends on the data size and mainly the size of the SOM grid.I couldn't manage the memory problem and therefore, I recommend single core processing at the moment. But nevertheless, the implementation of the algorithm is carefully done for all those important matrix calculations, such as `scipy` sparse matrix and `numexpr` for calculation of Euclidean distance. 8 | 2. PCA (or RandomPCA (default)) initialization, using `sklearn` or random initialization. 9 | 3. component plane visualization (different modes). 10 | 4. Hitmap. 11 | 5. U-Matrix visualization. 12 | 6. 1-d or 2-d SOM with only rectangular, planar grid. (works well in comparison with hexagonal shape, when I was checking in Matlab with somtoolbox). 13 | 7. Different methods for function approximation and predictions (mostly using Sklearn). 14 | 15 | 16 | ### Dependencies: 17 | SOMPY has the following dependencies (tested only with Python 2.7x): 18 | - numpy 19 | - scipy 20 | - scikit-learn 21 | - numexpr 22 | - matplotlib 23 | - pandas 24 | - ipdb 25 | 26 | ### Installation: 27 | ```Python 28 | python setup.py install 29 | ``` 30 | 31 | 32 | Many thanks to @sebastiandev, the library is now standardized in a pythonic tradition. Below you can see some basic examples, showing how to use the library. 33 | But I recommend you to go through the codes. There are several functionalities already implemented, but not documented. I would be very happy to add your new examples here. 34 | 35 | [Basice Example](https://gist.github.com/sevamoo/035c56e7428318dd3065013625f12a11) 36 | 37 | ### Citation 38 | 39 | There is no published paper about this library. However if possible, please cite the library as follows: 40 | 41 | ``` 42 | Main Contributers: 43 | Vahid Moosavi @sevamoo 44 | Sebastian Packmann @sebastiandev 45 | Iván Vallés @ivallesp 46 | ``` 47 | 48 | 49 | For more information, you can contact me via sevamoo@gmail.com or svm@arch.ethz.ch, but please report an issue first. 50 | 51 | 52 | 53 | 54 | Thanks a lot. 55 | Best Vahid Moosavi 56 | -------------------------------------------------------------------------------- /sompy/visualization/histogram.py: -------------------------------------------------------------------------------- 1 | from .view import MatplotView 2 | from matplotlib import pyplot as plt 3 | from matplotlib import cm 4 | from matplotlib.colors import LogNorm 5 | import numpy as np 6 | 7 | 8 | class Hist2d(MatplotView): 9 | 10 | def _fill_hist(self, x, y, mapsize, data_coords, what='train'): 11 | x = np.arange(.5, mapsize[1]+.5, 1) 12 | y = np.arange(.5, mapsize[0]+.5, 1) 13 | X, Y = np.meshgrid(x, y) 14 | 15 | if what == 'train': 16 | a = plt.hist2d(x, y, bins=(mapsize[1], mapsize[0]), alpha=.0, 17 | cmap=cm.jet) 18 | area = a[0].T * 12 19 | plt.scatter(data_coords[:, 1], mapsize[0] - .5 - data_coords[:, 0], 20 | s=area.flatten(), alpha=.9, c='None', marker='o', 21 | cmap='jet', linewidths=3, edgecolor='r') 22 | 23 | else: 24 | a = plt.hist2d(x, y, bins=(mapsize[1], mapsize[0]), alpha=.0, 25 | cmap=cm.jet, norm=LogNorm()) 26 | area = a[0].T*50 27 | plt.scatter(data_coords[:, 1] + .5, 28 | mapsize[0] - .5 - data_coords[:, 0], 29 | s=area, alpha=0.9, c='None', marker='o', cmap='jet', 30 | linewidths=3, edgecolor='r') 31 | plt.scatter(data_coords[:, 1]+.5, mapsize[0]-.5-data_coords[:, 0], 32 | s=area, alpha=0.2, c='b', marker='o', cmap='jet', 33 | linewidths=3, edgecolor='r') 34 | 35 | plt.xlim(0, mapsize[1]) 36 | plt.ylim(0, mapsize[0]) 37 | 38 | def show(self, som, data=None): 39 | # First Step: show the hitmap of all the training data 40 | coord = som.bmu_ind_to_xy(som.project_data(som.data_raw)) 41 | 42 | self.prepare() 43 | 44 | ax = self._fig.add_subplot(111) 45 | ax.xaxis.set_ticks([i for i in range(0, som.codebook.mapsize[1])]) 46 | ax.yaxis.set_ticks([i for i in range(0, som.codebook.mapsize[0])]) 47 | ax.xaxis.set_ticklabels([]) 48 | ax.yaxis.set_ticklabels([]) 49 | ax.grid(True, linestyle='-', linewidth=.5) 50 | 51 | self._fill_hist(coord[:, 1], coord[:, 0], som.codebook.mapsize, 52 | som.bmu_ind_to_xy(np.arange(som.codebook.nnodes))) 53 | 54 | if data: 55 | coord_d = som.bmu_ind_to_xy(som.project_data(data)) 56 | self._fill_hist(coord[:, 1], coord[:, 0], som.codebook.mapsize, 57 | coord_d, 'data') 58 | 59 | plt.show() 60 | -------------------------------------------------------------------------------- /sompy/visualization/dotmap.py: -------------------------------------------------------------------------------- 1 | from .view import MatplotView 2 | from matplotlib import pyplot as plt 3 | import numpy as np 4 | 5 | 6 | class DotMapView(MatplotView): 7 | 8 | def init_figure(self, dim, cols): 9 | no_row_in_plot = dim/cols + 1 10 | no_col_in_plot = dim if no_row_in_plot <= 1 else cols 11 | h = .1 12 | w = .1 13 | self.width = no_col_in_plot*2.5*(1+w) 14 | self.height = no_row_in_plot*2.5*(1+h) 15 | self.prepare() 16 | 17 | def plot(self, data, coords, msz0, msz1, colormap, dlen, dim, rows, cols): 18 | for i in range(dim): 19 | plt.subplot(rows, cols, i+1) 20 | 21 | # This uses the colors uniquely for each record, while in normal 22 | # views, it is based on the values within each dimensions. This is 23 | # important when we are dealing with time series. Where we don't 24 | # want to normalize colors within each time period, rather we like 25 | # to see the patterns of each data records in time. 26 | mn = np.min(data[:, :], axis=1) 27 | mx = np.max(data[:, :], axis=1) 28 | 29 | for j in range(dlen): 30 | plt.scatter(coords[j, 1], 31 | msz0-1-coords[j, 0], 32 | c=data[j, i], 33 | vmax=mx[j], vmin=mn[j], 34 | s=90, 35 | marker='.', 36 | edgecolor='None', 37 | cmap=colormap, 38 | alpha=1) 39 | 40 | eps = .0075 41 | plt.xlim(0-eps, msz1-1+eps) 42 | plt.ylim(0-eps, msz0-1+eps) 43 | plt.xticks([]) 44 | plt.yticks([]) 45 | 46 | def show(self, som, which_dim='all', colormap=None, cols=None): 47 | plt.cm.get_cmap(colormap) if colormap else plt.cm.get_cmap('RdYlBu_r') 48 | 49 | data = som.data_raw 50 | msz0, msz1 = som.codebook.mapsize 51 | coords = som.bmu_ind_to_xy(som.project_data(data))[:, :2] 52 | cols = cols if cols else 8 # 8 is arbitrary 53 | rows = data.shape[1]/cols+1 54 | 55 | if which_dim == 'all': 56 | dim = data.shape[0] 57 | self.init_figure(dim, cols) 58 | self.plot(data, coords, msz0, msz1, colormap, data.shape[0], 59 | data.shape[1], rows, cols) 60 | 61 | else: 62 | dim = 1 if type(which_dim) is int else len(which_dim) 63 | self.init_figure(dim, cols) 64 | self.plot(data, coords, msz0, msz1, colormap, data.shape[0], 65 | len(which_dim), rows, cols) 66 | 67 | plt.tight_layout() 68 | plt.subplots_adjust(hspace=.16, wspace=.05) 69 | -------------------------------------------------------------------------------- /sompy/examples/main.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from sompy.sompy import SOMFactory 3 | import pandas as pd 4 | import glob 5 | import os 6 | 7 | 8 | # read in all csvs from folder 9 | path = '..\\..\\data\\' 10 | all_files = glob.glob(os.path.join(path, "*.csv")) 11 | 12 | # concat into one df 13 | df_from_each_file = (pd.read_csv(f, skiprows = 31) for f in all_files) 14 | concatenated_df = pd.concat(df_from_each_file, ignore_index=True) 15 | 16 | # get columns Lat, Long, Mean Temp, Max Temp, Min temp, Precipitation 17 | data = concatenated_df[['Lat', 'Long', 'Tm', 'Tx', 'Tn', 'P']] 18 | data = data.apply(pd.to_numeric, errors='coerce') 19 | data = data.dropna(how='any') 20 | names = ['Latitude', "longitude", 'Monthly Median temperature (C)','Monthly Max temperature (C)', 'Monthly Min temperature (C)', 'Monthly total precipitation (mm)'] 21 | 22 | print(data.head()) 23 | 24 | # create the SOM network and train it. You can experiment with different normalizations and initializations 25 | sm = SOMFactory().build(data.values, normalization = 'var', initialization='pca', component_names=names) 26 | sm.train(n_job=1, verbose=False, train_rough_len=2, train_finetune_len=5) 27 | 28 | # The quantization error: average distance between each data vector and its BMU. 29 | # The topographic error: the proportion of all data vectors for which first and second BMUs are not adjacent units. 30 | topographic_error = sm.calculate_topographic_error() 31 | quantization_error = np.mean(sm._bmu[1]) 32 | print ("Topographic error = %s; Quantization error = %s" % (topographic_error, quantization_error)) 33 | 34 | # component planes view 35 | from sompy.visualization.mapview import View2D 36 | view2D = View2D(10,10,"rand data",text_size=12) 37 | view2D.show(sm, col_sz=4, which_dim="all", desnormalize=True) 38 | 39 | # U-matrix plot 40 | from sompy.visualization.umatrix import UMatrixView 41 | 42 | umat = UMatrixView(width=10,height=10,title='U-matrix') 43 | umat.show(sm) 44 | 45 | # do the K-means clustering on the SOM grid, sweep across k = 2 to 20 46 | from sompy.visualization.hitmap import HitMapView 47 | K = 20 # stop at this k for SSE sweep 48 | K_opt = 18 # optimal K already found 49 | [labels, km, norm_data] = sm.cluster(K,K_opt) 50 | hits = HitMapView(20,20,"Clustering",text_size=12) 51 | a=hits.show(sm) 52 | 53 | import gmplot 54 | 55 | gmap = gmplot.GoogleMapPlotter(54.2, -124.875224, 6) 56 | j = 0 57 | for i in km.cluster_centers_: 58 | gmap.marker(i[0],i[1],'red', title="Centroid " + str(j)) 59 | j += 1 60 | 61 | gmap.draw("centroids_map.html") 62 | 63 | 64 | from bs4 import BeautifulSoup 65 | 66 | def insertapikey(fname, apikey): 67 | """put the google api key in a html file""" 68 | def putkey(htmltxt, apikey, apistring=None): 69 | """put the apikey in the htmltxt and return soup""" 70 | if not apistring: 71 | apistring = "https://maps.googleapis.com/maps/api/js?key=%s&callback=initMap" 72 | soup = BeautifulSoup(htmltxt, 'html.parser') 73 | body = soup.body 74 | src = apistring % (apikey, ) 75 | tscript = soup.new_tag("script", src=src, async="defer") 76 | body.insert(-1, tscript) 77 | return soup 78 | htmltxt = open(fname, 'r').read() 79 | soup = putkey(htmltxt, apikey) 80 | newtxt = soup.prettify() 81 | open(fname, 'w').write(newtxt) 82 | API_KEY= 'YOUR API KEY HERE' 83 | insertapikey("centroids_map.html", API_KEY) 84 | 85 | 86 | gmap = gmplot.GoogleMapPlotter(54.2, -124.875224, 6) 87 | j = 0 88 | for i in km.cluster_centers_: 89 | gmap.marker(i[0],i[1],'red', title="Centroid " + str(j)) 90 | j += 1 91 | 92 | gmap.draw("centroids_map.html") 93 | -------------------------------------------------------------------------------- /sompy/visualization/umatrix.py: -------------------------------------------------------------------------------- 1 | from .view import MatplotView 2 | from matplotlib import pyplot as plt 3 | from pylab import imshow, contour 4 | from math import sqrt 5 | import numpy as np 6 | import scipy 7 | 8 | 9 | class UMatrixView(MatplotView): 10 | 11 | def build_u_matrix(self, som, distance=1, row_normalized=False): 12 | UD2 = som.calculate_map_dist() 13 | Umatrix = np.zeros((som.codebook.nnodes, 1)) 14 | codebook = som.codebook.matrix 15 | if row_normalized: 16 | vector = som._normalizer.normalize_by(codebook.T, codebook.T, 17 | method='var').T 18 | else: 19 | vector = codebook 20 | 21 | for i in range(som.codebook.nnodes): 22 | codebook_i = vector[i][np.newaxis, :] 23 | neighborbor_ind = UD2[i][0:] <= distance 24 | neighborbor_codebooks = vector[neighborbor_ind] 25 | Umatrix[i] = scipy.spatial.distance_matrix( 26 | codebook_i, neighborbor_codebooks).mean() 27 | 28 | return Umatrix.reshape(som.codebook.mapsize) 29 | 30 | def show(self, som, distance2=1, row_normalized=False, show_data=True, 31 | contooor=True, blob=False, labels=False): 32 | umat = self.build_u_matrix(som, distance=distance2, 33 | row_normalized=row_normalized) 34 | msz = som.codebook.mapsize 35 | proj = som.project_data(som.data_raw) 36 | coord = som.bmu_ind_to_xy(proj) 37 | 38 | self._fig, ax = plt.subplots(1, 1) 39 | imshow(umat, cmap=plt.cm.get_cmap('RdYlBu_r'), alpha=1) 40 | 41 | if contooor: 42 | mn = np.min(umat.flatten()) 43 | mx = np.max(umat.flatten()) 44 | std = np.std(umat.flatten()) 45 | md = np.median(umat.flatten()) 46 | mx = md + 0*std 47 | contour(umat, np.linspace(mn, mx, 15), linewidths=0.7, 48 | cmap=plt.cm.get_cmap('Blues')) 49 | 50 | if show_data: 51 | plt.scatter(coord[:, 1], coord[:, 0], s=2, alpha=1., c='Gray', 52 | marker='o', cmap='jet', linewidths=3, edgecolor='Gray') 53 | plt.axis('off') 54 | 55 | if labels: 56 | if labels is True: 57 | labels = som.build_data_labels() 58 | for label, x, y in zip(labels, coord[:, 1], coord[:, 0]): 59 | plt.annotate(str(label), xy=(x, y), 60 | horizontalalignment='center', 61 | verticalalignment='center') 62 | 63 | ratio = float(msz[0])/(msz[0]+msz[1]) 64 | self._fig.set_size_inches((1-ratio)*15, ratio*15) 65 | plt.tight_layout() 66 | plt.subplots_adjust(hspace=.00, wspace=.000) 67 | sel_points = list() 68 | 69 | if blob: 70 | from skimage.color import rgb2gray 71 | from skimage.feature import blob_log 72 | 73 | image = 1 / umat 74 | rgb2gray(image) 75 | 76 | # 'Laplacian of Gaussian' 77 | blobs = blob_log(image, max_sigma=5, num_sigma=4, threshold=.152) 78 | blobs[:, 2] = blobs[:, 2] * sqrt(2) 79 | imshow(umat, cmap=plt.cm.get_cmap('RdYlBu_r'), alpha=1) 80 | sel_points = list() 81 | 82 | for blob in blobs: 83 | row, col, r = blob 84 | c = plt.Circle((col, row), r, color='red', linewidth=2, 85 | fill=False) 86 | ax.add_patch(c) 87 | dist = scipy.spatial.distance_matrix( 88 | coord[:, :2], np.array([row, col])[np.newaxis, :]) 89 | sel_point = dist <= r 90 | plt.plot(coord[:, 1][sel_point[:, 0]], 91 | coord[:, 0][sel_point[:, 0]], '.r') 92 | sel_points.append(sel_point[:, 0]) 93 | 94 | plt.show() 95 | return sel_points, umat 96 | -------------------------------------------------------------------------------- /sompy/examples/centroids_map.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Google Maps - pygmaps 6 | 7 | 163 | 164 | 165 |
166 | 167 | 168 | -------------------------------------------------------------------------------- /sompy/codebook.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | from sklearn.decomposition import PCA 4 | #from sklearn.decomposition import RandomizedPCA# (randomizedpca is deprecated) 5 | from .decorators import timeit 6 | 7 | 8 | class InvalidNodeIndexError(Exception): 9 | pass 10 | 11 | 12 | class InvalidMapsizeError(Exception): 13 | pass 14 | 15 | 16 | class Codebook(object): 17 | 18 | def __init__(self, mapsize, lattice='rect'): 19 | self.lattice = lattice 20 | 21 | if 2 == len(mapsize): 22 | _size = [1, np.max(mapsize)] if 1 == np.min(mapsize) else mapsize 23 | 24 | elif 1 == len(mapsize): 25 | _size = [1, mapsize[0]] 26 | print('input was considered as the numbers of nodes') 27 | print('map size is [{dlen},{dlen}]'.format(dlen=int(mapsize[0]/2))) 28 | else: 29 | raise InvalidMapsizeError( 30 | "Mapsize is expected to be a 2 element list or a single int") 31 | 32 | self.mapsize = _size 33 | self.nnodes = mapsize[0]*mapsize[1] 34 | self.matrix = np.asarray(self.mapsize) 35 | self.initialized = False 36 | 37 | @timeit() 38 | def random_initialization(self, data): 39 | """ 40 | :param data: data to use for the initialization 41 | :returns: initialized matrix with same dimension as input data 42 | """ 43 | mn = np.tile(np.min(data, axis=0), (self.nnodes, 1)) 44 | mx = np.tile(np.max(data, axis=0), (self.nnodes, 1)) 45 | self.matrix = mn + (mx-mn)*(np.random.rand(self.nnodes, data.shape[1])) 46 | self.initialized = True 47 | 48 | @timeit() 49 | def pca_linear_initialization(self, data): 50 | """ 51 | We initialize the map, just by using the first two first eigen vals and 52 | eigenvectors 53 | Further, we create a linear combination of them in the new map by 54 | giving values from -1 to 1 in each 55 | 56 | X = UsigmaWT 57 | XTX = Wsigma^2WT 58 | T = XW = Usigma 59 | 60 | // Transformed by W EigenVector, can be calculated by multiplication 61 | // PC matrix by eigenval too 62 | // Further, we can get lower ranks by using just few of the eigen 63 | // vevtors 64 | 65 | T(2) = U(2)sigma(2) = XW(2) ---> 2 is the number of selected 66 | eigenvectors 67 | 68 | (*) Note that 'X' is the covariance matrix of original data 69 | 70 | :param data: data to use for the initialization 71 | :returns: initialized matrix with same dimension as input data 72 | """ 73 | cols = self.mapsize[1] 74 | coord = None 75 | pca_components = None 76 | 77 | if np.min(self.mapsize) > 1: 78 | coord = np.zeros((self.nnodes, 2)) 79 | pca_components = 2 80 | 81 | for i in range(0, self.nnodes): 82 | coord[i, 0] = int(i / cols) # x 83 | coord[i, 1] = int(i % cols) # y 84 | 85 | elif np.min(self.mapsize) == 1: 86 | coord = np.zeros((self.nnodes, 1)) 87 | pca_components = 1 88 | 89 | for i in range(0, self.nnodes): 90 | coord[i, 0] = int(i % cols) # y 91 | 92 | mx = np.max(coord, axis=0) 93 | mn = np.min(coord, axis=0) 94 | coord = (coord - mn)/(mx-mn) 95 | coord = (coord - .5)*2 96 | me = np.mean(data, 0) 97 | data = (data - me) 98 | tmp_matrix = np.tile(me, (self.nnodes, 1)) 99 | 100 | # Randomized PCA is scalable 101 | #pca = RandomizedPCA(n_components=pca_components) # RandomizedPCA is deprecated. 102 | pca = PCA(n_components=pca_components, svd_solver='randomized') 103 | 104 | pca.fit(data) 105 | eigvec = pca.components_ 106 | eigval = pca.explained_variance_ 107 | norms = np.sqrt(np.einsum('ij,ij->i', eigvec, eigvec)) 108 | eigvec = ((eigvec.T/norms)*eigval).T 109 | 110 | for j in range(self.nnodes): 111 | for i in range(eigvec.shape[0]): 112 | tmp_matrix[j, :] = tmp_matrix[j, :] + coord[j, i]*eigvec[i, :] 113 | 114 | self.matrix = np.around(tmp_matrix, decimals=6) 115 | self.initialized = True 116 | 117 | def grid_dist(self, node_ind): 118 | """ 119 | Calculates grid distance based on the lattice type. 120 | 121 | :param node_ind: number between 0 and number of nodes-1. Depending on 122 | the map size, starting from top left 123 | :returns: matrix representing the distance matrix 124 | """ 125 | if self.lattice == 'rect': 126 | return self._rect_dist(node_ind) 127 | 128 | elif self.lattice == 'hexa': 129 | return self._hexa_dist(node_ind) 130 | 131 | def _hexa_dist(self, node_ind): 132 | raise NotImplementedError() 133 | 134 | def _rect_dist(self, node_ind): 135 | """ 136 | Calculates the distance of the specified node to the other nodes in the 137 | matrix, generating a distance matrix 138 | 139 | Ej. The distance matrix for the node_ind=5, that corresponds to 140 | the_coord (1,1) 141 | array([[2, 1, 2, 5], 142 | [1, 0, 1, 4], 143 | [2, 1, 2, 5], 144 | [5, 4, 5, 8]]) 145 | 146 | :param node_ind: number between 0 and number of nodes-1. Depending on 147 | the map size, starting from top left 148 | :returns: matrix representing the distance matrix 149 | """ 150 | rows = self.mapsize[0] 151 | cols = self.mapsize[1] 152 | dist = None 153 | 154 | # bmu should be an integer between 0 to no_nodes 155 | if 0 <= node_ind <= (rows*cols): 156 | node_col = int(node_ind % cols) 157 | node_row = int(node_ind / cols) 158 | else: 159 | raise InvalidNodeIndexError( 160 | "Node index '%s' is invalid" % node_ind) 161 | 162 | if rows > 0 and cols > 0: 163 | r = np.arange(0, rows, 1)[:, np.newaxis] 164 | c = np.arange(0, cols, 1) 165 | dist2 = (r-node_row)**2 + (c-node_col)**2 166 | 167 | dist = dist2.ravel() 168 | else: 169 | raise InvalidMapsizeError( 170 | "One or both of the map dimensions are invalid. " 171 | "Cols '%s', Rows '%s'".format(cols=cols, rows=rows)) 172 | 173 | return dist 174 | -------------------------------------------------------------------------------- /sompy/visualization/mapview.py: -------------------------------------------------------------------------------- 1 | import matplotlib 2 | from .view import MatplotView 3 | from matplotlib import pyplot as plt 4 | import numpy as np 5 | #import ipdb 6 | 7 | 8 | class MapView(MatplotView): 9 | 10 | def _calculate_figure_params(self, som, which_dim, col_sz): 11 | 12 | # add this to avoid error when normalization is not used 13 | if som._normalizer: 14 | codebook = som._normalizer.denormalize_by(som.data_raw, som.codebook.matrix) 15 | else: 16 | codebook = som.codebook.matrix 17 | 18 | indtoshow, sV, sH = None, None, None 19 | 20 | if which_dim == 'all': 21 | dim = som._dim 22 | row_sz = np.ceil(float(dim) / col_sz) 23 | msz_row, msz_col = som.codebook.mapsize 24 | ratio_hitmap = msz_row / float(msz_col) 25 | ratio_fig = row_sz / float(col_sz) 26 | indtoshow = np.arange(0, dim).T 27 | sH, sV = 16, 16*ratio_fig*ratio_hitmap 28 | 29 | elif type(which_dim) == int: 30 | dim = 1 31 | msz_row, msz_col = som.codebook.mapsize 32 | ratio_hitmap = msz_row / float(msz_col) 33 | indtoshow = np.zeros(1) 34 | indtoshow[0] = int(which_dim) 35 | sH, sV = 16, 16 * ratio_hitmap 36 | 37 | elif type(which_dim) == list: 38 | max_dim = codebook.shape[1] 39 | dim = len(which_dim) 40 | row_sz = np.ceil(float(dim) / col_sz) 41 | msz_row, msz_col = som.codebook.mapsize 42 | ratio_hitmap = msz_row / float(msz_col) 43 | ratio_fig = row_sz / float(col_sz) 44 | indtoshow = np.asarray(which_dim).T 45 | sH, sV = 16, 16*ratio_fig*ratio_hitmap 46 | 47 | no_row_in_plot = dim / col_sz + 1 # 6 is arbitrarily selected 48 | if no_row_in_plot <= 1: 49 | no_col_in_plot = dim 50 | else: 51 | no_col_in_plot = col_sz 52 | 53 | axis_num = 0 54 | 55 | width = sH 56 | height = sV 57 | 58 | return (width, height, indtoshow, no_row_in_plot, no_col_in_plot, 59 | axis_num) 60 | 61 | 62 | class View2D(MapView): 63 | 64 | def show(self, som, what='codebook', which_dim='all', cmap=None, 65 | col_sz=None, desnormalize=False): 66 | (self.width, self.height, indtoshow, no_row_in_plot, no_col_in_plot, 67 | axis_num) = self._calculate_figure_params(som, which_dim, col_sz) 68 | self.prepare() 69 | 70 | if not desnormalize: 71 | codebook = som.codebook.matrix 72 | else: 73 | codebook = som._normalizer.denormalize_by(som.data_raw, som.codebook.matrix) 74 | 75 | if which_dim == 'all': 76 | names = som._component_names[0] 77 | elif type(which_dim) == int: 78 | names = [som._component_names[0][which_dim]] 79 | elif type(which_dim) == list: 80 | names = som._component_names[0][which_dim] 81 | 82 | 83 | while axis_num < len(indtoshow): 84 | axis_num += 1 85 | ax = plt.subplot(no_row_in_plot, no_col_in_plot, axis_num) 86 | ind = int(indtoshow[axis_num-1]) 87 | 88 | min_color_scale = np.mean(codebook[:, ind].flatten()) - 1 * np.std(codebook[:, ind].flatten()) 89 | max_color_scale = np.mean(codebook[:, ind].flatten()) + 1 * np.std(codebook[:, ind].flatten()) 90 | min_color_scale = min_color_scale if min_color_scale >= min(codebook[:, ind].flatten()) else \ 91 | min(codebook[:, ind].flatten()) 92 | max_color_scale = max_color_scale if max_color_scale <= max(codebook[:, ind].flatten()) else \ 93 | max(codebook[:, ind].flatten()) 94 | norm = matplotlib.colors.Normalize(vmin=min_color_scale, vmax=max_color_scale, clip=True) 95 | 96 | mp = codebook[:, ind].reshape(som.codebook.mapsize[0], 97 | som.codebook.mapsize[1]) 98 | pl = plt.pcolor(mp[::-1], norm=norm) 99 | plt.axis([0, som.codebook.mapsize[1], 0, som.codebook.mapsize[0]]) 100 | plt.title(names[axis_num - 1]) 101 | ax.set_yticklabels([]) 102 | ax.set_xticklabels([]) 103 | plt.colorbar(pl) 104 | 105 | #plt.show() 106 | 107 | 108 | class View2DPacked(MapView): 109 | 110 | def _set_axis(self, ax, msz0, msz1): 111 | plt.axis([0, msz0, 0, msz1]) 112 | plt.axis('off') 113 | ax.axis('off') 114 | 115 | def show(self, som, what='codebook', which_dim='all', cmap=None, 116 | col_sz=None): 117 | if col_sz is None: 118 | col_sz = 6 119 | (self.width, self.height, indtoshow, no_row_in_plot, no_col_in_plot, 120 | axis_num) = self._calculate_figure_params(som, which_dim, col_sz) 121 | codebook = som.codebook.matrix 122 | 123 | cmap = cmap or plt.cm.get_cmap('RdYlBu_r') 124 | msz0, msz1 = som.codebook.mapsize 125 | compname = som.component_names 126 | if what == 'codebook': 127 | h = .1 128 | w = .1 129 | self.width = no_col_in_plot*2.5*(1+w) 130 | self.height = no_row_in_plot*2.5*(1+h) 131 | self.prepare() 132 | 133 | while axis_num < len(indtoshow): 134 | axis_num += 1 135 | ax = self._fig.add_subplot(no_row_in_plot, no_col_in_plot, 136 | axis_num) 137 | ax.axis('off') 138 | ind = int(indtoshow[axis_num-1]) 139 | mp = codebook[:, ind].reshape(msz0, msz1) 140 | plt.imshow(mp[::-1], norm=None, cmap=cmap) 141 | self._set_axis(ax, msz0, msz1) 142 | 143 | if self.show_text is True: 144 | plt.title(compname[0][ind]) 145 | font = {'size': self.text_size} 146 | plt.rc('font', **font) 147 | if what == 'cluster': 148 | try: 149 | codebook = getattr(som, 'cluster_labels') 150 | except: 151 | codebook = som.cluster() 152 | 153 | h = .2 154 | w = .001 155 | self.width = msz0/2 156 | self.height = msz1/2 157 | self.prepare() 158 | 159 | ax = self._fig.add_subplot(1, 1, 1) 160 | mp = codebook[:].reshape(msz0, msz1) 161 | plt.imshow(mp[::-1], cmap=cmap) 162 | 163 | self._set_axis(ax, msz0, msz1) 164 | 165 | plt.subplots_adjust(hspace=h, wspace=w) 166 | 167 | plt.show() 168 | 169 | 170 | class View1D(MapView): 171 | 172 | def show(self, som, what='codebook', which_dim='all', cmap=None, 173 | col_sz=None): 174 | (self.width, self.height, indtoshow, no_row_in_plot, no_col_in_plot, 175 | axis_num) = self._calculate_figure_params(som, which_dim, col_sz) 176 | self.prepare() 177 | 178 | codebook = som.codebook.matrix 179 | 180 | while axis_num < len(indtoshow): 181 | axis_num += 1 182 | plt.subplot(no_row_in_plot, no_col_in_plot, axis_num) 183 | ind = int(indtoshow[axis_num-1]) 184 | mp = codebook[:, ind] 185 | plt.plot(mp, '-k', linewidth=0.8) 186 | 187 | #plt.show() 188 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /sompy/sompy.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Author: Vahid Moosavi (sevamoo@gmail.com) 4 | # Chair For Computer Aided Architectural Design, ETH Zurich 5 | # Future Cities Lab 6 | # www.vahidmoosavi.com 7 | 8 | # Contributor: Sebastian Packmann (sebastian.packmann@gmail.com) 9 | 10 | 11 | import tempfile 12 | import os 13 | import itertools 14 | import logging 15 | 16 | import numpy as np 17 | 18 | from time import time 19 | from multiprocessing.dummy import Pool 20 | from multiprocessing import cpu_count 21 | from scipy.sparse import csr_matrix 22 | from sklearn import neighbors 23 | from sklearn.externals.joblib import Parallel, delayed, load, dump 24 | import sys 25 | 26 | from .decorators import timeit 27 | from .codebook import Codebook 28 | from .neighborhood import NeighborhoodFactory 29 | from .normalization import NormalizatorFactory 30 | 31 | #lbugnon 32 | #import ipdb 33 | import sompy 34 | # 35 | 36 | class ComponentNamesError(Exception): 37 | pass 38 | 39 | 40 | class LabelsError(Exception): 41 | pass 42 | 43 | 44 | class SOMFactory(object): 45 | 46 | @staticmethod 47 | def build(data, 48 | mapsize=None, 49 | mask=None, 50 | mapshape='planar', 51 | lattice='rect', 52 | normalization='var', 53 | initialization='pca', 54 | neighborhood='gaussian', 55 | training='batch', 56 | name='sompy', 57 | component_names=None): 58 | """ 59 | :param data: data to be clustered, represented as a matrix of n rows, 60 | as inputs and m cols as input features 61 | :param neighborhood: neighborhood object calculator. Options are: 62 | - gaussian 63 | - bubble 64 | - manhattan (not implemented yet) 65 | - cut_gaussian (not implemented yet) 66 | - epanechicov (not implemented yet) 67 | 68 | :param normalization: normalizer object calculator. Options are: 69 | - var 70 | 71 | :param mapsize: tuple/list defining the dimensions of the som. 72 | If single number is provided is considered as the number of nodes. 73 | :param mask: mask 74 | :param mapshape: shape of the som. Options are: 75 | - planar 76 | - toroid (not implemented yet) 77 | - cylinder (not implemented yet) 78 | 79 | :param lattice: type of lattice. Options are: 80 | - rect 81 | - hexa (not implemented yet) 82 | 83 | :param initialization: method to be used for initialization of the som. 84 | Options are: 85 | - pca 86 | - random 87 | 88 | :param name: name used to identify the som 89 | :param training: Training mode (seq, batch) 90 | """ 91 | if normalization: 92 | normalizer = NormalizatorFactory.build(normalization) 93 | else: 94 | normalizer = None 95 | neighborhood_calculator = NeighborhoodFactory.build(neighborhood) 96 | return SOM(data, neighborhood_calculator, normalizer, mapsize, mask, 97 | mapshape, lattice, initialization, training, name, component_names) 98 | 99 | 100 | class SOM(object): 101 | 102 | def __init__(self, 103 | data, 104 | neighborhood, 105 | normalizer=None, 106 | mapsize=None, 107 | mask=None, 108 | mapshape='planar', 109 | lattice='rect', 110 | initialization='pca', 111 | training='batch', 112 | name='sompy', 113 | component_names=None): 114 | """ 115 | Self Organizing Map 116 | 117 | :param data: data to be clustered, represented as a matrix of n rows, 118 | as inputs and m cols as input features 119 | :param neighborhood: neighborhood object calculator. 120 | :param normalizer: normalizer object calculator. 121 | :param mapsize: tuple/list defining the dimensions of the som. If 122 | single number is provided is considered as the number of nodes. 123 | :param mask: mask 124 | :param mapshape: shape of the som. 125 | :param lattice: type of lattice. 126 | :param initialization: method to be used for initialization of the som. 127 | :param name: name used to identify the som 128 | :param training: Training mode (seq, batch) 129 | """ 130 | self._data = normalizer.normalize(data) if normalizer else data 131 | self._normalizer = normalizer 132 | self._dim = data.shape[1] 133 | self._dlen = data.shape[0] 134 | self._dlabel = None 135 | self._bmu = None 136 | 137 | self.name = name 138 | self.data_raw = data 139 | self.neighborhood = neighborhood 140 | self.mapshape = mapshape 141 | self.initialization = initialization 142 | self.mask = mask or np.ones([1, self._dim]) 143 | mapsize = self.calculate_map_size(lattice) if not mapsize else mapsize 144 | self.codebook = Codebook(mapsize, lattice) 145 | self.training = training 146 | self._component_names = self.build_component_names() if component_names is None else [component_names] 147 | self._distance_matrix = self.calculate_map_dist() 148 | 149 | @property 150 | def component_names(self): 151 | return self._component_names 152 | 153 | @component_names.setter 154 | def component_names(self, compnames): 155 | if self._dim == len(compnames): 156 | self._component_names = np.asarray(compnames)[np.newaxis, :] 157 | else: 158 | raise ComponentNamesError('Component names should have the same ' 159 | 'size as the data dimension/features') 160 | 161 | def build_component_names(self): 162 | cc = ['Variable-' + str(i+1) for i in range(0, self._dim)] 163 | return np.asarray(cc)[np.newaxis, :] 164 | 165 | @property 166 | def data_labels(self): 167 | return self._dlabel 168 | 169 | @data_labels.setter 170 | def data_labels(self, labels): 171 | """ 172 | Set labels of the training data, it should be in the format of a list 173 | of strings 174 | """ 175 | if labels.shape == (1, self._dlen): 176 | label = labels.T 177 | elif labels.shape == (self._dlen, 1): 178 | label = labels 179 | elif labels.shape == (self._dlen,): 180 | label = labels[:, np.newaxis] 181 | else: 182 | raise LabelsError('wrong label format') 183 | 184 | self._dlabel = label 185 | 186 | def build_data_labels(self): 187 | cc = ['dlabel-' + str(i) for i in range(0, self._dlen)] 188 | return np.asarray(cc)[:, np.newaxis] 189 | 190 | def calculate_map_dist(self): 191 | """ 192 | Calculates the grid distance, which will be used during the training 193 | steps. It supports only planar grids for the moment 194 | """ 195 | nnodes = self.codebook.nnodes 196 | 197 | distance_matrix = np.zeros((nnodes, nnodes)) 198 | for i in range(nnodes): 199 | distance_matrix[i] = self.codebook.grid_dist(i).reshape(1, nnodes) 200 | return distance_matrix 201 | 202 | @timeit() 203 | def train(self, 204 | n_job=1, 205 | shared_memory=False, 206 | verbose='info', 207 | train_rough_len=None, 208 | train_rough_radiusin=None, 209 | train_rough_radiusfin=None, 210 | train_finetune_len=None, 211 | train_finetune_radiusin=None, 212 | train_finetune_radiusfin=None, 213 | train_len_factor=1, 214 | maxtrainlen=np.Inf): 215 | """ 216 | Trains the som 217 | 218 | :param n_job: number of jobs to use to parallelize the traning 219 | :param shared_memory: flag to active shared memory 220 | :param verbose: verbosity, could be 'debug', 'info' or None 221 | :param train_len_factor: Factor that multiply default training lenghts (similar to "training" parameter in the matlab version). (lbugnon) 222 | """ 223 | logging.root.setLevel( 224 | getattr(logging, verbose.upper()) if verbose else logging.ERROR) 225 | 226 | logging.info(" Training...") 227 | logging.debug(( 228 | "--------------------------------------------------------------\n" 229 | " details: \n" 230 | " > data len is {data_len} and data dimension is {data_dim}\n" 231 | " > map size is {mpsz0},{mpsz1}\n" 232 | " > array size in log10 scale is {array_size}\n" 233 | " > number of jobs in parallel: {n_job}\n" 234 | " -------------------------------------------------------------\n") 235 | .format(data_len=self._dlen, 236 | data_dim=self._dim, 237 | mpsz0=self.codebook.mapsize[0], 238 | mpsz1=self.codebook.mapsize[1], 239 | array_size=np.log10( 240 | self._dlen * self.codebook.nnodes * self._dim), 241 | n_job=n_job)) 242 | 243 | if self.initialization == 'random': 244 | self.codebook.random_initialization(self._data) 245 | 246 | elif self.initialization == 'pca': 247 | self.codebook.pca_linear_initialization(self._data) 248 | 249 | self.rough_train(njob=n_job, shared_memory=shared_memory, trainlen=train_rough_len, 250 | radiusin=train_rough_radiusin, radiusfin=train_rough_radiusfin,trainlen_factor=train_len_factor,maxtrainlen=maxtrainlen) 251 | self.finetune_train(njob=n_job, shared_memory=shared_memory, trainlen=train_finetune_len, 252 | radiusin=train_finetune_radiusin, radiusfin=train_finetune_radiusfin,trainlen_factor=train_len_factor,maxtrainlen=maxtrainlen) 253 | logging.debug( 254 | " --------------------------------------------------------------") 255 | logging.info(" Final quantization error: %f" % np.mean(self._bmu[1])) 256 | 257 | def _calculate_ms_and_mpd(self): 258 | mn = np.min(self.codebook.mapsize) 259 | max_s = max(self.codebook.mapsize[0], self.codebook.mapsize[1]) 260 | 261 | if mn == 1: 262 | mpd = float(self.codebook.nnodes*10)/float(self._dlen) 263 | else: 264 | mpd = float(self.codebook.nnodes)/float(self._dlen) 265 | ms = max_s/2.0 if mn == 1 else max_s 266 | 267 | return ms, mpd 268 | 269 | def rough_train(self, njob=1, shared_memory=False, trainlen=None, radiusin=None, radiusfin=None,trainlen_factor=1,maxtrainlen=np.Inf): 270 | logging.info(" Rough training...") 271 | 272 | ms, mpd = self._calculate_ms_and_mpd() 273 | #lbugnon: add maxtrainlen 274 | trainlen = min(int(np.ceil(30*mpd)),maxtrainlen) if not trainlen else trainlen 275 | #print("maxtrainlen %d",maxtrainlen) 276 | #lbugnon: add trainlen_factor 277 | trainlen=int(trainlen*trainlen_factor) 278 | 279 | if self.initialization == 'random': 280 | radiusin = max(1, np.ceil(ms/3.)) if not radiusin else radiusin 281 | radiusfin = max(1, radiusin/6.) if not radiusfin else radiusfin 282 | 283 | elif self.initialization == 'pca': 284 | radiusin = max(1, np.ceil(ms/8.)) if not radiusin else radiusin 285 | radiusfin = max(1, radiusin/4.) if not radiusfin else radiusfin 286 | 287 | self._batchtrain(trainlen, radiusin, radiusfin, njob, shared_memory) 288 | 289 | def finetune_train(self, njob=1, shared_memory=False, trainlen=None, radiusin=None, radiusfin=None,trainlen_factor=1,maxtrainlen=np.Inf): 290 | logging.info(" Finetune training...") 291 | 292 | ms, mpd = self._calculate_ms_and_mpd() 293 | 294 | #lbugnon: add maxtrainlen 295 | if self.initialization == 'random': 296 | trainlen = min(int(np.ceil(50*mpd)),maxtrainlen) if not trainlen else trainlen 297 | radiusin = max(1, ms/12.) if not radiusin else radiusin # from radius fin in rough training 298 | radiusfin = max(1, radiusin/25.) if not radiusfin else radiusfin 299 | 300 | elif self.initialization == 'pca': 301 | trainlen = min(int(np.ceil(40*mpd)),maxtrainlen) if not trainlen else trainlen 302 | radiusin = max(1, np.ceil(ms/8.)/4) if not radiusin else radiusin 303 | radiusfin = 1 if not radiusfin else radiusfin # max(1, ms/128) 304 | 305 | #print("maxtrainlen %d",maxtrainlen) 306 | 307 | #lbugnon: add trainlen_factor 308 | trainlen=int(trainlen_factor*trainlen) 309 | 310 | 311 | self._batchtrain(trainlen, radiusin, radiusfin, njob, shared_memory) 312 | 313 | def _batchtrain(self, trainlen, radiusin, radiusfin, njob=1, 314 | shared_memory=False): 315 | radius = np.linspace(radiusin, radiusfin, trainlen) 316 | 317 | if shared_memory: 318 | data = self._data 319 | data_folder = tempfile.mkdtemp() 320 | data_name = os.path.join(data_folder, 'data') 321 | dump(data, data_name) 322 | data = load(data_name, mmap_mode='r') 323 | 324 | else: 325 | data = self._data 326 | 327 | bmu = None 328 | 329 | # X2 is part of euclidean distance (x-y)^2 = x^2 +y^2 - 2xy that we use 330 | # for each data row in bmu finding. 331 | # Since it is a fixed value we can skip it during bmu finding for each 332 | # data point, but later we need it calculate quantification error 333 | fixed_euclidean_x2 = np.einsum('ij,ij->i', data, data) 334 | 335 | logging.info(" radius_ini: %f , radius_final: %f, trainlen: %d\n" % 336 | (radiusin, radiusfin, trainlen)) 337 | 338 | for i in range(trainlen): 339 | t1 = time() 340 | neighborhood = self.neighborhood.calculate( 341 | self._distance_matrix, radius[i], self.codebook.nnodes) 342 | bmu = self.find_bmu(data, njb=njob) 343 | self.codebook.matrix = self.update_codebook_voronoi(data, bmu, 344 | neighborhood) 345 | 346 | #lbugnon: ojo! aca el bmy[1] a veces da negativo, y despues de eso se rompe...hay algo raro ahi 347 | qerror = (i + 1, round(time() - t1, 3), 348 | np.mean(np.sqrt(bmu[1] + fixed_euclidean_x2))) #lbugnon: ojo aca me tiró un warning, revisar (commit sinc: 965666d3d4d93bcf48e8cef6ea2c41a018c1cb83 ) 349 | #lbugnon 350 | #ipdb.set_trace() 351 | # 352 | logging.info( 353 | " epoch: %d ---> elapsed time: %f, quantization error: %f\n" % 354 | qerror) 355 | if np.any(np.isnan(qerror)): 356 | logging.info("nan quantization error, exit train\n") 357 | 358 | #sys.exit("quantization error=nan, exit train") 359 | 360 | bmu[1] = np.sqrt(bmu[1] + fixed_euclidean_x2) 361 | self._bmu = bmu 362 | 363 | @timeit(logging.DEBUG) 364 | def find_bmu(self, input_matrix, njb=1, nth=1): 365 | """ 366 | Finds the best matching unit (bmu) for each input data from the input 367 | matrix. It does all at once parallelizing the calculation instead of 368 | going through each input and running it against the codebook. 369 | 370 | :param input_matrix: numpy matrix representing inputs as rows and 371 | features/dimension as cols 372 | :param njb: number of jobs to parallelize the search 373 | :returns: the best matching unit for each input 374 | """ 375 | dlen = input_matrix.shape[0] 376 | y2 = np.einsum('ij,ij->i', self.codebook.matrix, self.codebook.matrix) 377 | if njb == -1: 378 | njb = cpu_count() 379 | 380 | pool = Pool(njb) 381 | chunk_bmu_finder = _chunk_based_bmu_find 382 | 383 | def row_chunk(part): 384 | return part * dlen // njb 385 | 386 | def col_chunk(part): 387 | return min((part+1)*dlen // njb, dlen) 388 | 389 | chunks = [input_matrix[row_chunk(i):col_chunk(i)] for i in range(njb)] 390 | b = pool.map(lambda chk: chunk_bmu_finder(chk, self.codebook.matrix, y2, nth=nth), chunks) 391 | pool.close() 392 | pool.join() 393 | bmu = np.asarray(list(itertools.chain(*b))).T 394 | del b 395 | return bmu 396 | 397 | @timeit(logging.DEBUG) 398 | def update_codebook_voronoi(self, training_data, bmu, neighborhood): 399 | """ 400 | Updates the weights of each node in the codebook that belongs to the 401 | bmu's neighborhood. 402 | 403 | First finds the Voronoi set of each node. It needs to calculate a 404 | smaller matrix. 405 | Super fast comparing to classic batch training algorithm, it is based 406 | on the implemented algorithm in som toolbox for Matlab by Helsinky 407 | University. 408 | 409 | :param training_data: input matrix with input vectors as rows and 410 | vector features as cols 411 | :param bmu: best matching unit for each input data. Has shape of 412 | (2, dlen) where first row has bmu indexes 413 | :param neighborhood: matrix representing the neighborhood of each bmu 414 | 415 | :returns: An updated codebook that incorporates the learnings from the 416 | input data 417 | """ 418 | row = bmu[0].astype(int) 419 | col = np.arange(self._dlen) 420 | val = np.tile(1, self._dlen) 421 | P = csr_matrix((val, (row, col)), shape=(self.codebook.nnodes, 422 | self._dlen)) 423 | S = P.dot(training_data) 424 | 425 | # neighborhood has nnodes*nnodes and S has nnodes*dim 426 | # ---> Nominator has nnodes*dim 427 | nom = neighborhood.T.dot(S) 428 | nV = P.sum(axis=1).reshape(1, self.codebook.nnodes) 429 | denom = nV.dot(neighborhood.T).reshape(self.codebook.nnodes, 1) 430 | new_codebook = np.divide(nom, denom) 431 | 432 | return np.around(new_codebook, decimals=6) 433 | 434 | def project_data(self, data): 435 | """ 436 | Projects a data set to a trained SOM. It is based on nearest 437 | neighborhood search module of scikitlearn, but it is not that fast. 438 | """ 439 | clf = neighbors.KNeighborsClassifier(n_neighbors=1) 440 | labels = np.arange(0, self.codebook.matrix.shape[0]) 441 | clf.fit(self.codebook.matrix, labels) 442 | 443 | # The codebook values are all normalized 444 | # we can normalize the input data based on mean and std of 445 | # original data 446 | data = self._normalizer.normalize_by(self.data_raw, data) 447 | 448 | return clf.predict(data) 449 | 450 | def predict_by(self, data, target, k=5, wt='distance'): 451 | # here it is assumed that target is the last column in the codebook 452 | # and data has dim-1 columns 453 | dim = self.codebook.matrix.shape[1] 454 | ind = np.arange(0, dim) 455 | indX = ind[ind != target] 456 | x = self.codebook.matrix[:, indX] 457 | y = self.codebook.matrix[:, target] 458 | n_neighbors = k 459 | clf = neighbors.KNeighborsRegressor(n_neighbors, weights=wt) 460 | clf.fit(x, y) 461 | 462 | # The codebook values are all normalized 463 | # we can normalize the input data based on mean and std of 464 | # original data 465 | dimdata = data.shape[1] 466 | 467 | if dimdata == dim: 468 | data[:, target] = 0 469 | data = self._normalizer.normalize_by(self.data_raw, data) 470 | data = data[:, indX] 471 | 472 | elif dimdata == dim-1: 473 | data = self._normalizer.normalize_by(self.data_raw[:, indX], data) 474 | 475 | predicted_values = clf.predict(data) 476 | predicted_values = self._normalizer.denormalize_by( 477 | self.data_raw[:, target], predicted_values) 478 | return predicted_values 479 | 480 | def predict(self, x_test, k=5, wt='distance'): 481 | """ 482 | Similar to SKlearn we assume that we have X_tr, Y_tr and X_test. Here 483 | it is assumed that target is the last column in the codebook and data 484 | has dim-1 columns 485 | 486 | :param x_test: input vector 487 | :param k: number of neighbors to use 488 | :param wt: method to use for the weights 489 | (more detail in KNeighborsRegressor docs) 490 | :returns: predicted values for the input data 491 | """ 492 | target = self.data_raw.shape[1]-1 493 | x_train = self.codebook.matrix[:, :target] 494 | y_train = self.codebook.matrix[:, target] 495 | clf = neighbors.KNeighborsRegressor(k, weights=wt) 496 | clf.fit(x_train, y_train) 497 | 498 | # The codebook values are all normalized 499 | # we can normalize the input data based on mean and std of 500 | # original data 501 | x_test = self._normalizer.normalize_by( 502 | self.data_raw[:, :target], x_test) 503 | predicted_values = clf.predict(x_test) 504 | 505 | return self._normalizer.denormalize_by( 506 | self.data_raw[:, target], predicted_values) 507 | 508 | def find_k_nodes(self, data, k=5): 509 | from sklearn.neighbors import NearestNeighbors 510 | # we find the k most similar nodes to the input vector 511 | neighbor = NearestNeighbors(n_neighbors=k) 512 | neighbor.fit(self.codebook.matrix) 513 | 514 | # The codebook values are all normalized 515 | # we can normalize the input data based on mean and std of 516 | # original data 517 | return neighbor.kneighbors( 518 | self._normalizer.normalize_by(self.data_raw, data)) 519 | 520 | def bmu_ind_to_xy(self, bmu_ind): 521 | """ 522 | Translates a best matching unit index to the corresponding 523 | matrix x,y coordinates. 524 | 525 | :param bmu_ind: node index of the best matching unit 526 | (number of node from top left node) 527 | :returns: corresponding (x,y) coordinate 528 | """ 529 | rows = self.codebook.mapsize[0] 530 | cols = self.codebook.mapsize[1] 531 | 532 | # bmu should be an integer between 0 to no_nodes 533 | out = np.zeros((bmu_ind.shape[0], 3)) 534 | out[:, 2] = bmu_ind 535 | out[:, 0] = rows-1-bmu_ind / cols 536 | out[:, 0] = bmu_ind / cols 537 | out[:, 1] = bmu_ind % cols 538 | 539 | return out.astype(int) 540 | 541 | def cluster(self, n_clusters=8, opt = 0): 542 | import sklearn.cluster as clust 543 | 544 | print("Performing K-means SSE elbow sweep...") 545 | 546 | # generate the bootstrap samples 547 | BTS = 20 548 | BTS_SIZE = 0.8 549 | 550 | normalized_data = self._normalizer.denormalize_by(self.data_raw, 551 | self.codebook.matrix) 552 | 553 | if(opt == 0): 554 | bts_len = int(BTS_SIZE * len(normalized_data)) 555 | bootstrap_samples = [] 556 | for i in range(BTS): 557 | 558 | temp = [] 559 | for j in range(bts_len): 560 | index = np.random.randint(0,len(normalized_data)) 561 | temp.append(normalized_data[index]) 562 | temp = np.array(temp) 563 | bootstrap_samples.append(temp) 564 | 565 | SSE_BTS_K = [] 566 | for i in range(2,n_clusters+1): 567 | 568 | SSE_K = [] 569 | for l in range(BTS): 570 | print("Working on bootstrap sample " + str(l) + " K: " + str(i)) 571 | km = clust.KMeans(n_clusters=i).fit(bootstrap_samples[l]) 572 | SSE = 0 573 | # calculate the Sum of Square Errors and compute the elbow point 574 | for k in bootstrap_samples[l]: 575 | label = km.predict([k])[0] 576 | SSE = SSE + np.linalg.norm(k - km.cluster_centers_[label]) 577 | SSE_K.append(SSE) 578 | # average the bootstrapped SSE's 579 | SSE_BTS_K.append(np.sum(SSE_K) / float(BTS)) 580 | 581 | 582 | 583 | # find the index of the maximum value of the 1st difference and add 1 to get the optimal K 584 | first_diff = np.diff(SSE_BTS_K) 585 | print("SSE for k = 2 to " + str(n_clusters) + " " + str(SSE_BTS_K)) 586 | index = np.argmax(first_diff) + 1 587 | 588 | print("Optimal K = " + str(index)) 589 | 590 | else: 591 | index = opt 592 | 593 | 594 | km = clust.KMeans(n_clusters=index).fit(normalized_data) 595 | 596 | # print cluster centroids 597 | for i in range(index): 598 | print("Centroid " + str(i) + str(km.cluster_centers_[i])) 599 | 600 | self.cluster_labels = km.labels_ 601 | return km.labels_, km, normalized_data 602 | 603 | def predict_probability(self, data, target, k=5): 604 | """ 605 | Predicts probability of the input data to be target 606 | 607 | :param data: data to predict, it is assumed that 'target' is the last 608 | column in the codebook, so data hould have dim-1 columns 609 | :param target: target to predict probability 610 | :param k: k parameter on KNeighborsRegressor 611 | :returns: probability of data been target 612 | """ 613 | dim = self.codebook.matrix.shape[1] 614 | ind = np.arange(0, dim) 615 | indx = ind[ind != target] 616 | x = self.codebook.matrix[:, indx] 617 | y = self.codebook.matrix[:, target] 618 | 619 | clf = neighbors.KNeighborsRegressor(k, weights='distance') 620 | clf.fit(x, y) 621 | 622 | # The codebook values are all normalized 623 | # we can normalize the input data based on mean and std of 624 | # original data 625 | dimdata = data.shape[1] 626 | 627 | if dimdata == dim: 628 | data[:, target] = 0 629 | data = self._normalizer.normalize_by(self.data_raw, data) 630 | data = data[:, indx] 631 | 632 | elif dimdata == dim-1: 633 | data = self._normalizer.normalize_by(self.data_raw[:, indx], data) 634 | 635 | weights, ind = clf.kneighbors(data, n_neighbors=k, 636 | return_distance=True) 637 | weights = 1./weights 638 | sum_ = np.sum(weights, axis=1) 639 | weights = weights/sum_[:, np.newaxis] 640 | labels = np.sign(self.codebook.matrix[ind, target]) 641 | labels[labels >= 0] = 1 642 | 643 | # for positives 644 | pos_prob = labels.copy() 645 | pos_prob[pos_prob < 0] = 0 646 | pos_prob *= weights 647 | pos_prob = np.sum(pos_prob, axis=1)[:, np.newaxis] 648 | 649 | # for negatives 650 | neg_prob = labels.copy() 651 | neg_prob[neg_prob > 0] = 0 652 | neg_prob = neg_prob * weights * -1 653 | neg_prob = np.sum(neg_prob, axis=1)[:, np.newaxis] 654 | 655 | return np.concatenate((pos_prob, neg_prob), axis=1) 656 | 657 | def node_activation(self, data, target=None, wt='distance'): 658 | weights, ind = None, None 659 | 660 | if not target: 661 | clf = neighbors.KNeighborsClassifier( 662 | n_neighbors=self.codebook.nnodes) 663 | labels = np.arange(0, self.codebook.matrix.shape[0]) 664 | clf.fit(self.codebook.matrix, labels) 665 | 666 | # The codebook values are all normalized 667 | # we can normalize the input data based on mean and std of 668 | # original data 669 | data = self._normalizer.normalize_by(self.data_raw, data) 670 | weights, ind = clf.kneighbors(data) 671 | 672 | # Softmax function 673 | weights = 1./weights 674 | 675 | return weights, ind 676 | 677 | def calculate_topographic_error(self): 678 | bmus1 = self.find_bmu(self.data_raw, njb=1, nth=1) 679 | bmus2 = self.find_bmu(self.data_raw, njb=1, nth=2) 680 | bmus_gap = np.abs((self.bmu_ind_to_xy(np.array(bmus1[0]))[:, 0:2] - self.bmu_ind_to_xy(np.array(bmus2[0]))[:, 0:2]).sum(axis=1)) 681 | return np.mean(bmus_gap != 1) 682 | 683 | def calculate_map_size(self, lattice): 684 | """ 685 | Calculates the optimal map size given a dataset using eigenvalues and eigenvectors. Matlab ported 686 | :lattice: 'rect' or 'hex' 687 | :return: map sizes 688 | """ 689 | D = self.data_raw.copy() 690 | dlen = D.shape[0] 691 | dim = D.shape[1] 692 | munits = np.ceil(5 * (dlen ** 0.5)) 693 | A = np.ndarray(shape=[dim, dim]) + np.Inf 694 | 695 | for i in range(dim): 696 | D[:, i] = D[:, i] - np.mean(D[np.isfinite(D[:, i]), i]) 697 | 698 | for i in range(dim): 699 | for j in range(dim): 700 | c = D[:, i] * D[:, j] 701 | c = c[np.isfinite(c)] 702 | A[i, j] = sum(c) / len(c) 703 | A[j, i] = A[i, j] 704 | 705 | VS = np.linalg.eig(A) 706 | eigval = sorted(np.linalg.eig(A)[0]) 707 | if eigval[-1] == 0 or eigval[-2] * munits < eigval[-1]: 708 | ratio = 1 709 | else: 710 | ratio = np.sqrt(eigval[-1] / eigval[-2]) 711 | 712 | if lattice == "rect": 713 | size1 = min(munits, round(np.sqrt(munits / ratio))) 714 | else: 715 | size1 = min(munits, round(np.sqrt(munits / ratio*np.sqrt(0.75)))) 716 | 717 | size2 = round(munits / size1) 718 | 719 | return [int(size1), int(size2)] 720 | 721 | 722 | # Since joblib.delayed uses Pickle, this method needs to be a top level 723 | # method in order to be pickled 724 | # Joblib is working on adding support for cloudpickle or dill which will allow 725 | # class methods to be pickled 726 | # when that that comes out we can move this to SOM class 727 | def _chunk_based_bmu_find(input_matrix, codebook, y2, nth=1): 728 | """ 729 | Finds the corresponding bmus to the input matrix. 730 | 731 | :param input_matrix: a matrix of input data, representing input vector as 732 | rows, and vectors features/dimention as cols 733 | when parallelizing the search, the input_matrix can be 734 | a sub matrix from the bigger matrix 735 | :param codebook: matrix of weights to be used for the bmu search 736 | :param y2: 737 | """ 738 | dlen = input_matrix.shape[0] 739 | nnodes = codebook.shape[0] 740 | bmu = np.empty((dlen, 2)) 741 | 742 | # It seems that small batches for large dlen is really faster: 743 | # that is because of ddata in loops and n_jobs. for large data it slows 744 | # down due to memory needs in parallel 745 | blen = min(50, dlen) 746 | i0 = 0 747 | 748 | while i0+1 <= dlen: 749 | low = i0 750 | high = min(dlen, i0+blen) 751 | i0 = i0+blen 752 | ddata = input_matrix[low:high+1] 753 | d = np.dot(codebook, ddata.T) 754 | d *= -2 755 | d += y2.reshape(nnodes, 1) 756 | bmu[low:high+1, 0] = np.argpartition(d, nth, axis=0)[nth-1] 757 | bmu[low:high+1, 1] = np.partition(d, nth, axis=0)[nth-1] 758 | del ddata 759 | 760 | return bmu 761 | 762 | 763 | 764 | -------------------------------------------------------------------------------- /data/eng-climate-summaries-British Columbia-10,2017.csv: -------------------------------------------------------------------------------- 1 | "Environment and Climate Change Canada" 2 | "Monthly Values for October - 2017" 3 | 4 | "Legend" 5 | "Stn_Name","Station Name" 6 | "Lat","Latitude (North + , degrees)" 7 | "Long","Longitude (West - , degrees)" 8 | "Prov","Province" 9 | "Tm","Mean Temperature (°C)" 10 | "DwTm","Days without Valid Mean Temperature" 11 | "D","Mean Temperature difference from Normal (1981-2010) (°C)" 12 | "Tx","Highest Monthly Maximum Temperature (°C)" 13 | "DwTx","Days without Valid Maximum Temperature" 14 | "Tn","Lowest Monthly Minimum Temperature (°C)" 15 | "DwTn","Days without Valid Minimum Temperature" 16 | "S","Snowfall (cm)" 17 | "DwS","Days without Valid Snowfall" 18 | "S%N","Percent of Normal (1981-2010) Snowfall" 19 | "P","Total Precipitation (mm)" 20 | "DwP","Days without Valid Precipitation" 21 | "P%N","Percent of Normal (1981-2010) Precipitation" 22 | "S_G","Snow on the ground at the end of the month (cm)" 23 | "Pd","Number of days with Precipitation 1.0 mm or more" 24 | "BS","Bright Sunshine (hours)" 25 | "DwBS","Days without Valid Bright Sunshine" 26 | "BS%","Percent of Normal (1981-2010) Bright Sunshine" 27 | "HDD","Degree Days below 18 °C" 28 | "CDD","Degree Days above 18 °C" 29 | "Clim_ID","Climate Identifier" 30 | "NA","Not Available" 31 | 32 | "Stn_Name","Lat","Long","Prov","Tm","DwTm","D","Tx","DwTx","Tn","DwTn","S","DwS","S%N","P","DwP","P%N","S_G","Pd","BS","DwBS","BS%","HDD","CDD","Clim_ID" 33 | "CHEMAINUS","48.935","-123.742","BC","10.9","0",NA,"18.5","0","4.0","0","0.0","0",NA,"153.9","0",NA,"0.0","9","","",NA,"220.4","0.0","1011500" 34 | "LAKE COWICHAN","48.829","-124.052","BC","9.2","14","-0.5","22.5","9","-1.0","10","0.0","29",NA,"267.0","15",NA,"","12","","",NA,"149.1","0.0","1012055" 35 | "DISCOVERY ISLAND","48.425","-123.226","BC","",,NA,"16.1","0","",,"",,NA,"",,NA,"","","",,NA,"","","1012475" 36 | "ESQUIMALT HARBOUR","48.432","-123.439","BC","10.6","0",NA,"18.8","0","4.0","0","",,NA,"110.8","0",NA,"","10","",,NA,"228.5","0.0","1012710" 37 | "GALIANO NORTH","48.985","-123.573","BC","11.1","4",NA,"18.5","4","5.0","4","0.0","4",NA,"76.8","4",NA,"0.0","7","","",NA,"186.5","0.0","10130MN" 38 | "MALAHAT","48.575","-123.530","BC","10.1","0",NA,"17.6","0","2.3","0","",,NA,"127.8","0",NA,"","10","",,NA,"244.4","0.0","1014820" 39 | "METCHOSIN","48.374","-123.561","BC","",,NA,"",,"",,"0.0","5",NA,"165.6","5",NA,"0.0","11","","",NA,"","","1015105" 40 | "NORTH COWICHAN","48.824","-123.718","BC","",,NA,"",,"",,"0.0","0","0.0","134.8","0","124.0","0.0","11","","",NA,"","","1015628" 41 | "NORTH COWICHAN","48.824","-123.719","BC","9.7","0",NA,"21.3","0","-0.5","0","",,NA,"128.2","0",NA,"","10","",,NA,"258.2","0.0","1015630" 42 | "NORTH PENDER ISLAND","48.764","-123.287","BC","11.3","12",NA,"20.5","12","5.0","12","0.0","12",NA,"53.6","12",NA,"","5","","",NA,"126.9","0.0","1015638" 43 | "RACE ROCKS","48.298","-123.531","BC","11.2","0",NA,"17.5","0","6.4","0","",,NA,"",,NA,"","","",,NA,"212.0","0.0","1016640" 44 | "SAANICHTON CDA","48.622","-123.419","BC","10.6","6","0.3","19.0","3","3.0","3","0.0","3",NA,"102.5","3",NA,"","9","","",NA,"183.8","0.0","1016940" 45 | "SALTSPRING ST MARY'S L","48.888","-123.546","BC","11.4","2","0.6","19.0","2","5.0","2","0.0","2",NA,"102.6","2",NA,"0.0","9","","",NA,"191.8","0.0","1016995" 46 | "SAANICHTON MT NEWTON","48.598","-123.427","BC","",,NA,"",,"",,"0.0","25",NA,"87.0","25",NA,"","6","","",NA,"","","1016RM0" 47 | "SATURNA CAPMON CS","48.775","-123.128","BC","10.2","3",NA,"18.1","3","3.8","1","",,NA,"24.2","3",NA,"","7","",,NA,"219.3","0.0","1017099" 48 | "SATURNA ISLAND CS","48.784","-123.045","BC","11.3","2",NA,"16.5","2","6.4","2","",,NA,"57.0","2",NA,"","8","",,NA,"193.7","0.0","1017101" 49 | "SHAWNIGAN LAKE","48.647","-123.626","BC","10.0","0","0.1","20.0","0","2.0","0","0.0","0","0.0","124.6","0","109.0","0.0","9","","",NA,"246.9","0.0","1017230" 50 | "SHERINGHAM POINT","48.377","-123.921","BC","11.0","0",NA,"17.1","0","6.5","0","",,NA,"124.4","0",NA,"","11","",,NA,"216.9","0.0","1017254" 51 | "VICTORIA UNIVERSITY CS","48.457","-123.305","BC","10.4","0",NA,"19.9","0","2.4","0","",,NA,"103.6","0",NA,"","10","",,NA,"234.6","0.0","1018598" 52 | "VICTORIA FRANCIS PARK","48.476","-123.443","BC","",,NA,"",,"",,"0.0","2",NA,"134.2","2",NA,"","10","","",NA,"","","1018605" 53 | "VICTORIA GONZALES CS","48.413","-123.325","BC","11.4","0",NA,"19.3","0","5.6","0","",,NA,"92.0","0",NA,"","10","",,NA,"205.7","0.0","1018611" 54 | "VICTORIA INTL A","48.647","-123.426","BC","10.2","0",NA,"19.8","0","1.2","0","0.0","0",NA,"92.3","0",NA,"","7","",,NA,"243.3","0.0","1018621" 55 | "WILLIAM HEAD","48.340","-123.539","BC","11.3","0","0.9","16.5","0","5.0","0","0.0","0","0.0","128.6","0","118.0","0.0","9","","",NA,"207.8","0.0","1018935" 56 | "BALLENAS ISLAND","49.350","-124.160","BC","11.0","0",NA,"17.4","0","7.2","0","",,NA,"61.0","0",NA,"","9","",,NA,"217.9","0.0","1020590" 57 | "CAMPBELL RIVER A","49.952","-125.273","BC","8.1","0","-0.5","20.5","0","-3.5","0","0.0","0","0.0","150.2","0","93.0","0.0","16","","",NA,"306.9","0.0","1021261" 58 | "CAPE MUDGE","49.998","-125.195","BC","10.3","0","0.7","20.0","0","4.5","0","0.0","0","0.0","120.2","0","71.0","0.0","14","","",NA,"238.9","0.0","1021330" 59 | "CHROME ISLAND","49.472","-124.683","BC","11.0","0",NA,"20.0","0","4.0","0","0.0","0",NA,"135.0","0",NA,"0.0","11","","",NA,"218.3","0.0","1021500" 60 | "COMOX A","49.717","-124.900","BC","9.7","0","0.3","19.6","0","1.6","0","0.0","0","0.0","90.3","0","74.0","","10","",,NA,"256.3","0.0","1021830" 61 | "CORTES ISLAND TIBER BAY","50.071","-124.949","BC","9.7","1",NA,"20.0","1","0.5","1","0.0","1",NA,"107.2","1",NA,"0.0","16","","",NA,"249.2","0.0","1021960" 62 | "COURTENAY GRANTHAM","49.763","-124.999","BC","9.5","7",NA,"19.5","7","4.0","7","0.0","7",NA,"110.6","7",NA,"","12","","",NA,"202.9","0.0","1021988" 63 | "COURTENAY PUNTLEDGE","49.686","-125.033","BC","9.3","8",NA,"20.5","5","-1.0","4","0.0","4",NA,"120.3","4",NA,"0.0","10","","",NA,"199.9","0.0","1021989" 64 | "ENTRANCE ISLAND","49.209","-123.811","BC","11.2","0",NA,"16.8","0","7.3","0","",,NA,"40.4","0",NA,"","7","",,NA,"211.5","0.0","1022689" 65 | "FANNY ISLAND","50.454","-125.993","BC","9.8","0",NA,"15.3","0","5.1","0","",,NA,"228.6","0",NA,"","15","",,NA,"255.5","0.0","1022795" 66 | "HERIOT BAY SE","50.099","-125.203","BC","9.6","3",NA,"19.0","3","3.5","3","0.0","3",NA,"115.0","3",NA,"0.0","14","","",NA,"235.2","0.0","1023462" 67 | "LITTLE QUALICUM HATCHERY","49.353","-124.512","BC","8.6","2","-0.2","19.5","2","-2.0","2","0.0","2",NA,"152.6","2",NA,"0.0","11","","",NA,"272.7","0.0","1024638" 68 | "NANAIMO A","49.054","-123.870","BC","9.6","0",NA,"19.5","0","-0.5","0","0.0","0",NA,"114.0","0",NA,"0.0","9","","",NA,"259.9","0.0","1025369" 69 | "NANAIMO CITY YARD","49.199","-123.988","BC","",,NA,"",,"",,"0.0","0","0.0","93.7","0","94.0","0.0","8","","",NA,"","","10253G0" 70 | "PINE ISLAND","50.976","-127.728","BC","9.9","1","0.1","17.5","1","5.5","1","0.0","1",NA,"301.6","1",NA,"0.0","17","","",NA,"242.1","0.0","1026170" 71 | "PORT HARDY A","50.681","-127.367","BC","8.3","0",NA,"15.9","0","-0.6","0","0.0","0",NA,"253.8","0",NA,"","17","",,NA,"301.3","0.0","1026271" 72 | "QUALICUM BEACH AIRPORT","49.337","-124.394","BC","9.1","0",NA,"18.2","0","0.7","0","",,NA,"91.0","0",NA,"","11","",,NA,"275.3","0.0","1026562" 73 | "QUALICUM R FISH RESEARCH","49.394","-124.617","BC","9.5","0","0.3","19.0","0","2.0","0","0.0","0","0.0","141.2","0","96.0","0.0","12","","",NA,"262.6","0.0","1026565" 74 | "QUINSAM RIVER HATCHERY","50.016","-125.304","BC","9.4","1","0.2","20.5","1","-0.5","1","0.0","1",NA,"165.4","1",NA,"","16","","",NA,"258.3","0.0","1026639" 75 | "SISTERS ISLAND","49.487","-124.435","BC","11.5","0",NA,"17.2","0","7.7","0","",,NA,"",,NA,"","","",,NA,"201.0","0.0","1027403" 76 | "ENTRANCE ISLAND","49.209","-123.809","BC","11.0","1",NA,"17.0","1","7.0","1","0.0","1",NA,"45.4","1",NA,"0.0","5","","",NA,"210.4","0.0","102BFHH" 77 | "CAPE BEALE LIGHT","48.786","-125.216","BC","11.1","0","0.6","18.5","0","5.5","0","0.0","0","0.0","288.8","0","102.0","0.0","15","","",NA,"213.0","0.0","1031316" 78 | "ESTEVAN POINT","49.383","-126.543","BC","10.8","0","0.5","17.5","0","3.5","0","0.0","0","0.0","279.6","0","85.0","0.0","17","","",NA,"222.9","0.0","1032730" 79 | "ESTEVAN POINT CS","49.383","-126.543","BC","10.4","11",NA,"17.1","11","3.3","10","",,NA,"195.3","11",NA,"","12","",,NA,"152.7","0.0","1032731" 80 | "LENNARD ISLAND","49.111","-125.923","BC","9.8","0",NA,"17.0","0","4.0","0","0.0","0","0.0","249.0","0","77.0","0.0","16","","",NA,"252.7","0.0","1034600" 81 | "NITINAT RIVER HATCHERY","48.859","-124.655","BC","10.0","0","-0.3","21.0","0","0.0","0","0.0","0","0.0","582.1","0","150.0","0.0","16","","",NA,"248.6","0.0","1035612" 82 | "NOOTKA LIGHTSTATION","49.600","-126.617","BC","11.2","2","0.3","20.0","2","4.0","2","0.0","2",NA,"318.4","2",NA,"0.0","13","","",NA,"198.6","0.0","1035614" 83 | "PACHENA POINT","48.723","-125.097","BC","9.8","2","-0.2","17.0","2","2.0","2","0.0","2",NA,"251.7","2",NA,"0.0","14","","",NA,"237.4","0.0","1035940" 84 | "PORT ALBERNI COX LAKE","49.202","-124.752","BC","10.2","15","0.3","19.5","15","1.0","15","0.0","15",NA,"208.6","15",NA,"0.0","9","","",NA,"124.9","0.0","1036208" 85 | "QUATSINO","50.534","-127.653","BC","9.5","4","-0.4","17.0","4","3.0","4","0.0","4",NA,"198.2","4",NA,"0.0","15","","",NA,"230.4","0.0","1036570" 86 | "PORT ALBERNI (AUT)","49.317","-124.927","BC","8.4","29",NA,"12.2","29","4.3","29","",,NA,"26.3","29",NA,"","2","",,NA,"19.2","0.0","1036B06" 87 | "SARTINE ISLAND (AUT)","50.821","-128.908","BC","10.2","1",NA,"13.1","1","6.9","0","",,NA,"159.4","1",NA,"","16","",,NA,"235.2","0.0","1037090" 88 | "SOLANDER ISLAND (AUT)","50.112","-127.940","BC","10.8","1",NA,"19.0","1","5.7","0","",,NA,"114.4","1",NA,"","15","",,NA,"216.1","0.0","1037553" 89 | "TAHSIS VILLAGE NORTH","49.932","-126.654","BC","9.9","11",NA,"19.5","11","0.0","11","0.0","11",NA,"563.4","11",NA,"0.0","12","","",NA,"162.2","0.0","1037899" 90 | "TOFINO A","49.082","-125.773","BC","9.9","3","0.0","18.0","3","2.0","3","0.0","3",NA,"255.0","3",NA,"0.0","12","","",NA,"226.6","0.0","1038205" 91 | "UCLUELET KENNEDY CAMP","48.945","-125.527","BC","10.2","0","0.0","19.5","0","1.5","0","0.0","0","0.0","314.4","0","91.0","0.0","14","","",NA,"241.5","0.0","1038332" 92 | "ZEBALLOS MURAUDE CREEK","50.053","-126.779","BC","10.5","1",NA,"22.0","1","1.5","1","0.0","1",NA,"517.9","1",NA,"0.0","16","","",NA,"224.6","0.0","1039035" 93 | "BOWEN ISLAND SUNSET PARK","49.360","-123.402","BC","",,NA,"",,"",,"0.0","22",NA,"111.4","22",NA,"","9","","",NA,"","","104091B" 94 | "GIBSONS GOWER POINT","49.386","-123.541","BC","10.6","0","0.1","18.0","0","4.5","0","0.0","0","0.0","99.8","0","71.0","0.0","12","","",NA,"230.0","0.0","1043152" 95 | "MERRY ISLAND LIGHTSTATION","49.468","-123.913","BC","11.1","0","0.3","17.5","0","6.0","0","0.0","0","0.0","83.4","0","79.0","0.0","10","","",NA,"213.0","0.0","1045100" 96 | "HOWE SOUND - PAM ROCKS","49.488","-123.299","BC","11.3","0",NA,"19.4","0","6.7","0","",,NA,"101.8","0",NA,"","12","",,NA,"208.3","0.0","10459NN" 97 | "PENDER HARBOUR","49.634","-124.032","BC","",,NA,"",,"",,"0.0","0",NA,"72.3","0",NA,"0.0","11","","",NA,"","","1046115" 98 | "PORT MELLON","49.526","-123.496","BC","10.0","0",NA,"21.0","0","3.1","0","",,NA,"241.1","0",NA,"","14","",,NA,"247.0","0.0","1046332" 99 | "POWELL RIVER A","49.834","-124.500","BC","8.6","0","-0.7","18.0","0","0.0","0","0.0","0","0.0","78.2","0","62.0","0.0","10","","",NA,"290.5","0.0","1046391" 100 | "POWELL RIVER","49.835","-124.497","BC","8.7","0",NA,"18.1","0","0.5","0","",,NA,"",,NA,"","","",,NA,"287.4","0.0","1046392" 101 | "SECHELT AUT","49.458","-123.715","BC","9.6","0",NA,"17.9","0","2.2","0","",,NA,"70.4","0",NA,"","12","",,NA,"261.0","0.0","1047172" 102 | "SQUAMISH AIRPORT","49.783","-123.161","BC","9.5","0",NA,"20.8","0","0.4","0","",,NA,"255.1","0",NA,"","12","",,NA,"262.1","0.0","10476F0" 103 | "WHISTLER","50.129","-122.955","BC","6.0","2","-0.7","18.5","2","-2.0","2","17.8","2",NA,"151.8","2",NA,"0.0","12","","",NA,"348.6","0.0","1048898" 104 | "CAPE ST JAMES","51.936","-131.016","BC","10.6","1",NA,"16.5","1","5.6","0","",,NA,"183.3","10",NA,"","18","",,NA,"222.3","0.0","1051351" 105 | "KINDAKUN ROCKS (AUT)","53.316","-132.772","BC","10.7","3",NA,"16.8","2","6.2","1","",,NA,"167.2","3",NA,"","15","",,NA,"205.7","0.0","1054222" 106 | "LANGARA","54.255","-133.058","BC","9.5","0","0.3","15.5","0","4.0","0","0.0","0","0.0","172.4","0","67.0","0.0","18","","",NA,"264.9","0.0","1054500" 107 | "ROSE SPIT (AUT)","54.159","-131.661","BC","9.4","0",NA,"15.0","0","0.9","0","",,NA,"191.3","0",NA,"","18","",,NA,"265.7","0.0","1056869" 108 | "SANDSPIT AIRPORT AUTO","53.249","-131.813","BC","9.7","4",NA,"16.1","4","2.1","0","",,NA,"167.1","4",NA,"","15","",,NA,"225.1","0.0","1057051" 109 | "SANDSPIT","53.254","-131.814","BC","10.3","5",NA,"16.4","5","3.5","5","",,NA,"142.8","5",NA,"","14","",,NA,"199.6","0.0","1057052" 110 | "ADDENBROKE ISLAND","51.604","-127.864","BC","10.0","0","0.4","16.5","0","4.0","0","0.0","0","0.0","633.2","0","147.0","0.0","20","","",NA,"248.9","0.0","1060080" 111 | "BELLA BELLA","52.185","-128.157","BC","",,NA,"",,"",,"",,NA,"350.4","1",NA,"","18","",,NA,"","","1060815" 112 | "BELLA COOLA A","52.388","-126.596","BC","8.7","0","0.4","19.0","0","-1.0","0","0.0","0","0.0","321.9","0","165.0","0.0","17","","",NA,"288.6","0.0","1060841" 113 | "BELLA COOLA AIRPORT","52.389","-126.587","BC","8.4","2",NA,"18.6","2","-1.2","1","",,NA,"285.8","2",NA,"","15","",,NA,"278.4","0.0","1060844" 114 | "BOAT BLUFF","52.643","-128.524","BC","10.3","0","1.2","20.0","0","3.5","0","0.0","0","0.0","775.6","0","123.0","0.0","17","","",NA,"240.2","0.0","1060901" 115 | "BONILLA ISLAND","53.493","-130.638","BC","10.1","0","0.3","16.0","0","5.0","0","0.0","0","0.0","192.0","0","76.0","0.0","17","","",NA,"244.5","0.0","1060902" 116 | "BONILLA ISLAND (AUT)","53.493","-130.639","BC","9.8","2",NA,"16.1","2","5.4","1","",,NA,"112.2","2",NA,"","15","",,NA,"239.2","0.0","1060R0K" 117 | "CATHEDRAL POINT (AUT)","52.187","-127.471","BC","9.7","2",NA,"18.6","1","4.1","1","",,NA,"812.6","2",NA,"","15","",,NA,"241.4","0.0","1061458" 118 | "CUMSHEWA ISLAND","53.030","-131.602","BC","10.5","2",NA,"17.2","2","5.6","1","",,NA,"94.6","2",NA,"","12","",,NA,"217.3","0.0","1062251" 119 | "DRYAD POINT","52.185","-128.112","BC","10.4","0","0.6","19.5","0","3.5","0","0.0","0","0.0","426.4","0","128.0","0.0","19","","",NA,"234.5","0.0","1062544" 120 | "EGG ISLAND","51.247","-127.835","BC","9.0","0","-0.3","14.0","0","4.0","0","0.0","0","0.0","377.2","0","115.0","0.0","15","","",NA,"278.7","0.0","1062646" 121 | "GREEN ISLAND","54.569","-130.708","BC","8.9","0","0.0","14.0","0","4.0","0","0.0","0","0.0","237.4","0","67.0","0.0","17","","",NA,"283.3","0.0","1063298" 122 | "GREY ISLET (AUT)","54.580","-130.698","BC","9.6","2",NA,"14.3","2","5.1","0","",,NA,"198.6","2",NA,"","16","",,NA,"243.6","0.0","1063303" 123 | "HERBERT ISLAND (AUT)","50.940","-127.632","BC","9.8","1",NA,"14.8","1","5.5","0","",,NA,"147.6","1",NA,"","15","",,NA,"244.6","0.0","1063461" 124 | "HOLLAND ROCK","54.172","-130.361","BC","9.1","0",NA,"16.9","0","4.5","0","",,NA,"173.2","0",NA,"","17","",,NA,"275.9","0.0","1063496" 125 | "IVORY ISLAND","52.270","-128.407","BC","10.4","0","0.6","20.5","0","4.0","0","0.0","0","0.0","365.6","0","103.0","0.0","18","","",NA,"237.0","0.0","1063690" 126 | "KEMANO","53.563","-127.943","BC","6.8","2","-0.4","19.0","1","-1.5","1","0.0","1",NA,"447.0","1",NA,"0.0","16","","",NA,"325.6","0.0","1064020" 127 | "KITIMAT TOWNSITE","54.054","-128.634","BC","6.2","6","-1.0","15.0","6","-5.0","6","9.0","6",NA,"394.6","6",NA,"0.0","14","","",NA,"294.9","0.0","1064320" 128 | "KITIMAT 2","54.010","-128.705","BC","6.8","4","-1.0","21.0","4","-1.0","4","8.0","4",NA,"477.6","4",NA,"0.0","17","","",NA,"301.4","0.0","1064321" 129 | "LUCY ISLAND LIGHTSTATION","54.296","-130.609","BC","9.5","1",NA,"15.1","1","5.1","0","",,NA,"",,NA,"","","",,NA,"256.4","0.0","1064728" 130 | "MCINNES ISLAND","52.262","-128.719","BC","10.9","0","1.0","18.5","0","5.0","0","0.0","0","0.0","328.4","0","105.0","0.0","17","","",NA,"221.2","0.0","1065010" 131 | "PRINCE RUPERT","54.286","-130.445","BC","8.1","4",NA,"17.9","4","0.2","4","",,NA,"229.0","4",NA,"","16","",,NA,"267.4","0.0","1066482" 132 | "PRINCE RUPERT MONT CIRC","54.320","-130.290","BC","",,NA,"",,"",,"0.0","12",NA,"431.8","12",NA,"0.0","12","","",NA,"","","1066488" 133 | "TERRACE PCC","54.502","-128.625","BC","6.5","1","-0.7","17.0","1","-3.0","1","0.0","1",NA,"261.4","1",NA,"0.0","14","","",NA,"344.4","0.0","1068131" 134 | "TERRACE A","54.469","-128.578","BC","5.6","0",NA,"15.1","0","-2.5","0","2.2","1",NA,"309.7","0",NA,"","18","",,NA,"385.2","0.0","1068134" 135 | "TRIPLE ISLAND","54.295","-130.880","BC","9.8","0",NA,"14.0","0","6.0","0","0.0","0",NA,"139.0","0",NA,"0.0","14","","",NA,"253.3","0.0","1068250" 136 | "EQUITY SILVER","54.199","-126.277","BC","2.0","0","0.3","16.0","0","-6.5","0","68.8","0","221.0","132.6","0","188.0","0.0","13","","",NA,"497.1","0.0","1072692" 137 | "HOUSTON","54.396","-126.668","BC","4.0","7",NA,"19.0","7","-6.0","7","0.0","14",NA,"80.6","14",NA,"0.0","5","","",NA,"336.2","0.0","1073615" 138 | "SMITHERS","54.825","-127.183","BC","4.2","12",NA,"15.8","12","-5.7","12","",,NA,"110.7","12",NA,"","7","",,NA,"262.1","0.0","1077499" 139 | "SMITHERS A","54.825","-127.183","BC","4.0","0","-0.4","16.5","0","-5.5","0","10.4","0","121.0","132.4","0","204.0","0.0","9","","",NA,"435.3","0.0","1077500" 140 | "SMITHERS AIRPORT AUTO","54.824","-127.189","BC","4.0","1",NA,"16.5","1","-4.8","0","",,NA,"129.0","1",NA,"1.0","11","",,NA,"420.0","0.0","1077501" 141 | "SUSKWA VALLEY","55.289","-127.171","BC","2.2","4","-2.0","15.0","4","-7.0","4","14.6","4",NA,"148.6","4",NA,"0.0","15","","",NA,"427.9","0.0","107G879" 142 | "OOTSA LAKESKINS LAKE CLIMATE","53.772","-125.997","BC","5.5","1",NA,"17.0","1","-3.2","0","",,NA,"51.7","1",NA,"","10","",,NA,"373.8","0.0","1085836" 143 | "PEMBERTON AIRPORT CS","50.306","-122.734","BC","8.3","0",NA,"20.4","0","-2.2","0","",,NA,"116.6","0",NA,"","12","",,NA,"301.2","0.0","1086082" 144 | "PUNTZI MOUNTAIN (AUT)","52.114","-124.136","BC","3.9","0",NA,"22.8","0","-11.4","0","",,NA,"36.9","0",NA,"","6","",,NA,"435.7","0.0","1086558" 145 | "TATLAYOKO LAKE RCS","51.675","-124.403","BC","5.1","0",NA,"21.1","0","-9.9","0","",,NA,"82.0","0",NA,"","9","",,NA,"400.3","0.0","1088015" 146 | "BURNS LAKE DECKER LAKE","54.383","-125.959","BC","2.8","0",NA,"17.6","0","-9.3","0","",,NA,"69.8","0",NA,"","10","",,NA,"472.2","0.0","1091174" 147 | "FORT ST JAMES","54.455","-124.286","BC","4.5","14","0.2","16.5","14","-5.0","14","2.0","14",NA,"37.0","14",NA,"0.0","6","","",NA,"229.2","0.0","1092970" 148 | "FORT ST JAMES AUTO","54.455","-124.286","BC","5.3","0",NA,"16.9","0","-5.2","0","",,NA,"60.6","0",NA,"","9","",,NA,"395.2","0.0","1092975" 149 | "MCLEESE LAKE GRANITE MT","52.531","-122.286","BC","3.9","16",NA,"21.0","11","-6.0","12","22.6","11",NA,"63.2","11",NA,"0.0","8","","",NA,"211.4","0.0","1095018" 150 | "PRINCE GEORGE","53.884","-122.678","BC","5.0","12",NA,"17.9","12","-9.6","12","",,NA,"45.6","12",NA,"","10","",,NA,"247.5","0.0","1096439" 151 | "PRINCE GEORGE AIRPORT AUTO","53.889","-122.672","BC","4.3","1",NA,"14.1","1","-9.9","0","",,NA,"49.8","3",NA,"","12","",,NA,"412.3","0.0","1096453" 152 | "PRINCE GEORGE STP","53.880","-122.768","BC","6.0","8","0.7","18.5","0","-3.0","8","2.0","0","45.0","53.0","0","88.0","0.0","14","","",NA,"274.9","0.0","1096468" 153 | "QUESNEL","53.026","-122.510","BC","5.6","10",NA,"19.1","10","-7.9","9","",,NA,"31.2","10",NA,"","5","",,NA,"259.5","0.0","1096629" 154 | "QUESNEL AIRPORT AUTO","53.027","-122.506","BC","5.3","0",NA,"19.4","0","-8.0","0","",,NA,"54.6","0",NA,"","9","",,NA,"394.2","0.0","1096631" 155 | "SPOKIN LAKE 4E","52.184","-121.686","BC","2.3","0","-1.0","19.0","0","-13.0","0","9.6","0","88.0","59.2","0","120.0","0.0","9","","",NA,"486.0","0.0","1097646" 156 | "WILLIAMS LAKE A","52.183","-122.054","BC","4.1","0",NA,"18.3","0","-7.2","0","16.2","0",NA,"45.4","0",NA,"","10","",,NA,"430.7","0.0","1098941" 157 | "VANDERHOOF","54.033","-124.017","BC","5.1","0","0.0","20.0","0","-11.0","0","0.6","0","8.0","51.2","0","101.0","0.0","11","","",NA,"400.7","0.0","1098D90" 158 | "108 MILE HOUSE ABEL LAKE","51.623","-121.263","BC","4.6","0",NA,"20.5","0","-6.5","0","8.0","0",NA,"34.5","0",NA,"0.0","6","","",NA,"414.7","0.0","109E7R6" 159 | "ABBOTSFORD A","49.025","-122.360","BC","10.2","1",NA,"20.3","0","1.1","1","0.0","0",NA,"186.6","0",NA,"","14","",,NA,"233.5","0.0","1100031" 160 | "AGASSIZ RCS","49.243","-121.760","BC","10.8","0","-0.4","20.8","0","2.6","0","",,NA,"253.3","0",NA,"","17","",,NA,"224.0","0.0","1100119" 161 | "AGASSIZ CDA","49.243","-121.760","BC","10.3","5","-0.6","20.0","3","3.0","2","0.0","2",NA,"236.5","2",NA,"0.0","16","","",NA,"199.8","0.0","1100120" 162 | "WHISTLER - NESTERS","50.129","-122.955","BC","6.1","0",NA,"18.7","0","-2.0","0","",,NA,"155.7","0",NA,"","10","",,NA,"370.4","0.0","1100875" 163 | "BLACKCOMB BASE SLIDING CENTER","50.102","-122.936","BC","5.8","1",NA,"17.9","1","-1.0","0","",,NA,"143.5","1",NA,"","11","",,NA,"367.0","0.0","1100881" 164 | "BURNABY SIMON FRASER U","49.278","-122.918","BC","11.0","15","1.4","18.0","15","5.0","15","0.0","15",NA,"31.8","15",NA,"0.0","4","","",NA,"112.7","0.0","1101158" 165 | "CALLAGHAN VALLEY","50.144","-123.111","BC","5.7","0",NA,"19.2","0","-1.2","0","",,NA,"208.3","0",NA,"","13","",,NA,"380.0","0.0","1101300" 166 | "CLOVERDALE EAST","49.109","-122.698","BC","11.4","0",NA,"21.5","0","2.5","0","0.0","0",NA,"166.1","0",NA,"0.0","11","","",NA,"205.0","0.0","1101708" 167 | "DELTA BURNS BOG","49.126","-123.002","BC","9.1","0",NA,"18.7","0","-1.2","0","",,NA,"115.3","0",NA,"","10","",,NA,"276.9","0.0","1102415" 168 | "DELTA TSAWWASSEN BEACH","49.011","-123.093","BC","9.5","1","-1.7","17.0","1","2.0","1","0.0","1",NA,"83.1","1",NA,"0.0","11","","",NA,"254.4","0.0","1102425" 169 | "FORT LANGLEY TELEGRAPH TRAIL","49.145","-122.551","BC","10.7","1",NA,"20.5","1","1.5","1","0.0","1",NA,"193.2","1",NA,"0.0","13","","",NA,"219.9","0.0","1102912" 170 | "HANEY UBC RF ADMIN","49.264","-122.573","BC","9.6","16","-0.3","19.5","16","3.5","16","0.0","16",NA,"107.2","16",NA,"","6","","",NA,"125.5","0.0","1103332" 171 | "MISSION WEST ABBEY","49.153","-122.271","BC","10.7","0","0.2","19.5","0","4.5","0","0.0","0","0.0","256.8","0","135.0","0.0","15","","",NA,"224.9","0.0","1105192" 172 | "RICHMOND OPERATIONS CENTRE","49.182","-123.078","BC","",,NA,"",,"",,"",,NA,"130.9","0",NA,"","11","",,NA,"","","1105210" 173 | "N VANC GROUSE MTN RESORT","49.381","-123.078","BC","5.9","4","0.1","22.0","4","-3.0","4","0.0","4",NA,"292.5","4",NA,"0.0","14","","",NA,"325.9","0.0","1105658" 174 | "N VANCOUVER WHARVES","49.315","-123.115","BC","",,NA,"",,"",,"0.0","11",NA,"397.2","11",NA,"","8","","",NA,"","","1105669" 175 | "PITT MEADOWS CS","49.208","-122.690","BC","10.2","0",NA,"21.5","0","0.9","0","",,NA,"197.1","0",NA,"","12","",,NA,"242.6","0.0","1106178" 176 | "POINT ATKINSON","49.330","-123.265","BC","10.9","0",NA,"17.1","0","6.3","0","",,NA,"75.2","0",NA,"","13","",,NA,"221.5","0.0","1106200" 177 | "PORT MOODY GLENAYRE","49.279","-122.881","BC","10.3","0","-0.1","20.0","0","4.0","0","0.0","0","0.0","238.3","0","117.0","0.0","12","","",NA,"237.5","0.0","1106CL2" 178 | "RICHMOND NATURE PARK","49.171","-123.093","BC","9.9","0","-0.4","19.5","0","0.0","0","0.0","0","0.0","152.7","0","120.0","0.0","14","","",NA,"252.1","0.0","1106PF7" 179 | "SANDHEADS CS","49.106","-123.303","BC","11.2","4",NA,"18.4","4","6.0","0","",,NA,"",,NA,"","","",,NA,"182.6","0.0","1107010" 180 | "SUMAS CANAL","49.113","-122.110","BC","11.2","21",NA,"22.0","14","5.5","15","0.0","14",NA,"187.0","14",NA,"0.0","10","","",NA,"68.4","0.0","1107785" 181 | "VANCOUVER SEA ISLAND CCG","49.183","-123.187","BC","9.9","2",NA,"16.7","2","1.9","1","",,NA,"129.0","2",NA,"","11","",,NA,"234.1","0.0","1108380" 182 | "VANCOUVER INTL A","49.195","-123.184","BC","9.8","1",NA,"16.8","1","0.6","0","0.0","1",NA,"114.3","1",NA,"","12","",,NA,"246.7","0.0","1108395" 183 | "VANCOUVER HARBOUR CS","49.295","-123.122","BC","10.8","0",NA,"19.0","0","5.1","0","",,NA,"184.3","0",NA,"","12","",,NA,"221.9","0.0","1108446" 184 | "WEST VANCOUVER AUT","49.347","-123.193","BC","10.9","0",NA,"19.7","0","3.6","0","",,NA,"171.0","0",NA,"","14","",,NA,"220.2","0.0","1108824" 185 | "WHITE ROCK CAMPBELL SCIENTIFIC","49.018","-122.784","BC","10.5","0",NA,"22.0","0","2.0","0","",,NA,"160.4","0",NA,"","12","",,NA,"231.9","0.0","1108910" 186 | "N VAN SEYMOUR HATCHERY","49.438","-122.967","BC","8.9","11","-0.6","19.0","10","1.0","11","0.0","10",NA,"242.4","10",NA,"","10","","",NA,"181.7","0.0","110N666" 187 | "HOPE A","49.368","-121.498","BC","10.5","10",NA,"21.6","10","2.9","10","",,NA,"196.1","10",NA,"","11","",,NA,"157.2","0.0","1113542" 188 | "HOPE AIRPORT","49.370","-121.493","BC","10.4","0",NA,"21.7","0","2.3","0","",,NA,"287.6","0",NA,"","14","",,NA,"236.8","0.0","1113543" 189 | "HOPE SLIDE","49.267","-121.233","BC","6.1","0","-0.4","18.0","0","-2.5","0","2.0","0","51.0","194.8","0","145.0","0.0","17","","",NA,"370.3","0.0","1113581" 190 | "LILLOOET","50.684","-121.934","BC","9.4","0",NA,"19.5","0","-1.0","0","",,NA,"",,NA,"","","",,NA,"266.8","0.0","1114619" 191 | "LYTTON A","50.224","-121.582","BC","10.0","14",NA,"19.3","14","0.7","13","",,NA,"56.7","14",NA,"","6","",,NA,"136.8","0.0","1114738" 192 | "LYTTON RCS","50.224","-121.582","BC","9.8","0",NA,"20.0","0","-1.0","0","",,NA,"51.7","0",NA,"","7","",,NA,"253.1","0.0","1114746" 193 | "JELLICOE","49.673","-120.333","BC","4.8","3",NA,"23.0","3","-7.5","3","8.0","3",NA,"53.2","3",NA,"0.0","10","","",NA,"369.6","0.0","1123721" 194 | "KELOWNA","49.957","-119.378","BC","6.6","10",NA,"18.1","10","-5.9","9","",,NA,"11.1","10",NA,"","4","",,NA,"240.0","0.0","1123939" 195 | "KELOWNA UBCO","49.941","-119.400","BC","7.8","0",NA,"18.5","0","-2.9","0","",,NA,"21.6","0",NA,"","6","",,NA,"317.7","0.0","1123996" 196 | "MERRITT","50.113","-120.778","BC","6.8","0",NA,"21.8","0","-7.8","0","",,NA,"37.2","16",NA,"","5","",,NA,"347.9","0.0","1125073" 197 | "MERRITT STP","50.114","-120.801","BC","7.3","0","-0.3","20.5","0","-5.0","0","0.0","0","0.0","56.6","0","205.0","0.0","8","","",NA,"331.3","0.0","1125079" 198 | "OKANAGAN CENTRE","50.056","-119.445","BC","9.3","0","0.2","17.0","0","0.5","0","0.0","0","0.0","39.4","0","124.0","0.0","9","","",NA,"270.2","0.0","1125700" 199 | "OLIVER STP","49.179","-119.545","BC","9.6","12","-0.1","20.0","11","-2.0","12","0.0","11",NA,"1.8","11",NA,"0.0","0","","",NA,"158.7","0.0","1125766" 200 | "OSOYOOS CS","49.028","-119.441","BC","9.2","0","-0.8","20.4","0","-2.7","0","",,NA,"6.2","0",NA,"","1","",,NA,"273.1","0.0","1125852" 201 | "PEACHLAND","49.783","-119.717","BC","9.2","0","-0.4","16.5","0","0.5","0","0.0","0","0.0","16.8","0","59.0","0.0","7","","",NA,"273.6","0.0","1126070" 202 | "PENTICTON A","49.463","-119.602","BC","8.1","0",NA,"19.2","0","-4.8","0","0.0","0",NA,"14.2","0",NA,"","4","",,NA,"306.8","0.0","1126146" 203 | "PRINCETON A","49.468","-120.513","BC","5.6","0","-1.2","21.0","0","-6.5","0","0.0","0","0.0","38.0","0","146.0","0.0","7","","",NA,"385.7","0.0","1126510" 204 | "VERNON AUTO","50.223","-119.194","BC","7.3","0",NA,"18.4","0","-2.7","0","",,NA,"35.4","0",NA,"","9","",,NA,"332.9","0.0","1128582" 205 | "VERNON NORTH","50.344","-119.271","BC","6.9","0","-0.9","17.5","0","-2.0","0","0.0","0","0.0","40.4","0","97.0","0.0","9","","",NA,"343.3","0.0","1128583" 206 | "PRINCETON CS","49.465","-120.510","BC","5.6","3",NA,"21.0","3","-6.5","1","",,NA,"37.7","3",NA,"","8","",,NA,"348.3","0.0","112FN0M" 207 | "SUMMERLAND CS","49.563","-119.649","BC","8.3","0","-0.7","17.7","0","-1.8","0","",,NA,"10.8","0",NA,"","3","",,NA,"300.8","0.0","112G8L1" 208 | "MIDWAY","49.004","-118.772","BC","6.2","0","-1.1","23.0","0","-7.5","0","0.0","0","0.0","25.0","0","102.0","0.0","5","","",NA,"367.3","0.0","1135126" 209 | "BILLINGS","49.017","-118.228","BC","6.5","5","-1.7","19.5","5","-3.0","5","0.0","5",NA,"22.0","5",NA,"0.0","4","","",NA,"300.0","0.0","1140876" 210 | "CASTLEGAR A","49.296","-117.633","BC","7.6","0","-0.4","19.0","0","-3.5","0","0.6","0","32.0","60.4","0","118.0","0.0","8","","",NA,"322.2","0.0","1141455" 211 | "CASTLEGAR BCHPA DAM","49.343","-117.774","BC","8.0","9","-0.4","17.5","4","0.0","5","0.0","4",NA,"37.4","4",NA,"0.0","8","","",NA,"219.3","0.0","1141457" 212 | "DUNCAN LAKE DAM","50.239","-116.972","BC","5.6","0","-0.8","17.0","0","-5.0","0","0.0","0","0.0","104.4","0","158.0","0.0","14","","",NA,"383.0","0.0","1142574" 213 | "KASLO","49.913","-116.921","BC","7.0","0","-0.4","20.0","0","-3.0","0","0.0","0","0.0","85.4","0","130.0","0.0","11","","",NA,"342.5","0.0","1143900" 214 | "NAKUSP CS","50.269","-117.817","BC","7.0","0",NA,"17.0","0","-3.1","0","",,NA,"77.9","0",NA,"","13","",,NA,"339.9","0.0","1145297" 215 | "NELSON NE","49.586","-117.206","BC","8.0","0",NA,"19.0","0","-2.0","0","0.0","0",NA,"78.2","0",NA,"0.0","10","","",NA,"310.9","0.0","1145442" 216 | "NEW DENVER","49.996","-117.370","BC","7.1","0","-0.4","18.0","0","-2.5","0","1.0","0","370.0","89.0","0","127.0","0.0","10","","",NA,"336.8","0.0","1145460" 217 | "NELSON CS","49.491","-117.305","BC","8.1","0",NA,"21.2","0","-1.6","0","",,NA,"58.0","0",NA,"","6","",,NA,"308.2","0.0","1145M29" 218 | "WARFIELD RCS","49.112","-117.739","BC","7.4","0",NA,"20.0","0","-2.4","0","",,NA,"52.8","0",NA,"","6","",,NA,"330.0","0.0","1148705" 219 | "CRESTON CAMPBELL SCIENTIFIC","49.082","-116.501","BC","7.7","0",NA,"18.6","0","-2.0","0","",,NA,"51.9","0",NA,"","6","",,NA,"319.6","0.0","114B1F0" 220 | "NELSON RIXEN CREEK","49.512","-117.399","BC","6.7","1",NA,"20.5","1","-3.5","1","2.4","1",NA,"73.8","1",NA,"0.0","8","","",NA,"340.0","0.0","114EMDM" 221 | "CRANBROOK A","49.612","-115.782","BC","4.7","2",NA,"18.6","0","-8.2","2","0.8","0",NA,"25.0","0",NA,"","8","",,NA,"385.5","0.0","1152105" 222 | "CRANBROOK AIRPORT AUTO","49.618","-115.789","BC","5.0","0",NA,"18.5","0","-7.9","0","",,NA,"17.9","0",NA,"","6","",,NA,"404.1","0.0","1152106" 223 | "FERNIE","49.489","-115.073","BC","5.7","12","0.3","19.0","12","-8.0","12","4.0","12",NA,"36.0","12",NA,"0.0","8","","",NA,"233.4","0.0","1152850" 224 | "FT STEELE DANDY CRK","49.524","-115.461","BC","2.7","27",NA,"15.0","22","-8.5","23","2.0","22",NA,"23.2","22",NA,"0.0","4","","",NA,"61.3","0.0","1153034" 225 | "KIMBERLEY PCC","49.632","-115.962","BC","5.5","14","-0.2","18.5","14","-6.5","14","10.0","14",NA,"27.0","14",NA,"0.0","5","","",NA,"213.3","0.0","1154203" 226 | "KOOTENAY NP WEST GATE","50.631","-116.061","BC","3.4","13","-1.7","14.0","13","-6.0","13","11.0","13",NA,"30.8","13",NA,"0.0","4","","",NA,"263.3","0.0","1154410" 227 | "SPARWOOD","49.745","-114.883","BC","4.4","0","-0.4","16.5","0","-8.0","0","8.0","0","71.0","83.2","0","170.0","0.0","10","","",NA,"421.9","0.0","1157630" 228 | "SPARWOOD CS","49.745","-114.884","BC","4.3","0",NA,"16.7","0","-8.1","0","",,NA,"49.0","20",NA,"","5","",,NA,"425.9","0.0","1157631" 229 | "WASA","49.807","-115.631","BC","5.3","0","-0.4","17.0","0","-6.0","0","6.6","0","263.0","34.8","0","137.0","0.0","7","","",NA,"393.3","0.0","1158730" 230 | "ASHCROFT","50.708","-121.281","BC","8.6","0",NA,"20.1","0","-1.7","0","",,NA,"20.8","0",NA,"","7","",,NA,"291.8","0.0","1160515" 231 | "BLUE RIVER A","52.129","-119.290","BC","3.8","0","-0.7","18.0","0","-8.0","0","20.2","0","203.0","104.2","0","102.0","0.0","15","","",NA,"439.8","0.0","1160899" 232 | "BLUE RIVER CS","52.129","-119.290","BC","3.7","0",NA,"18.0","0","-8.1","0","",,NA,"99.6","0",NA,"","15","",,NA,"443.7","0.0","1160H99" 233 | "CLEARWATER AUTO","51.653","-120.082","BC","5.3","0",NA,"18.6","0","-4.9","0","",,NA,"52.8","0",NA,"2.0","12","",,NA,"393.2","0.0","1161650" 234 | "CLINTON A","51.266","-121.685","BC","2.7","12",NA,"17.2","12","-11.0","12","",,NA,"13.9","12",NA,"","4","",,NA,"291.2","0.0","1161662" 235 | "CLINTON RCS","51.144","-121.505","BC","3.6","0",NA,"16.5","0","-7.1","0","",,NA,"30.4","0",NA,"","7","",,NA,"446.4","0.0","1161663" 236 | "CRISS CREEK","51.030","-120.728","BC","2.8","0","-0.5","19.0","0","-10.0","0","24.2","0","227.0","50.4","0","148.0","0.0","9","","",NA,"470.5","0.0","1162177" 237 | "DARFIELD","51.292","-120.183","BC","6.0","4","-0.4","17.5","2","-4.0","2","0.0","1",NA,"41.1","1",NA,"0.0","10","","",NA,"324.2","0.0","1162265" 238 | "KAMLOOPS A","50.703","-120.449","BC","7.8","0",NA,"19.2","0","-4.9","0","0.0","0",NA,"26.8","0",NA,"","8","",,NA,"316.9","0.0","1163781" 239 | "KAMLOOPS AUT","50.702","-120.442","BC","7.8","0",NA,"18.9","0","-4.5","0","",,NA,"25.1","0",NA,"","5","",,NA,"315.1","0.0","1163842" 240 | "100 MILE HOUSE 6NE","51.681","-121.217","BC","3.4","0",NA,"16.0","0","-8.0","0","10.2","0",NA,"34.0","0",NA,"0.0","8","","",NA,"452.7","0.0","1165793" 241 | "RED LAKE","50.935","-120.800","BC","3.9","0","-0.6","17.0","0","-6.0","0","31.6","0","266.0","62.8","0","177.0","0.0","10","","",NA,"436.5","0.0","1166658" 242 | "SILVER CREEK","50.545","-119.350","BC","6.0","0","-0.7","17.5","0","-6.0","0","0.0","0","0.0","35.9","0","73.0","0.0","10","","",NA,"372.0","0.0","1167337" 243 | "VAVENBY","51.576","-119.778","BC","5.2","0","-0.5","16.0","0","-5.5","0","0.0","0","0.0","52.6","0","122.0","0.0","9","","",NA,"397.8","0.0","1168520" 244 | "KAMLOOPS PRATT ROAD","50.630","-120.172","BC","6.3","4",NA,"15.0","4","-3.0","4","0.0","4",NA,"22.4","4",NA,"0.0","7","","",NA,"314.7","0.0","116C8P0" 245 | "SALMON ARM CS","50.703","-119.291","BC","6.8","0","-0.9","17.3","0","-4.0","0","",,NA,"42.2","0",NA,"","8","",,NA,"347.0","0.0","116FRMN" 246 | "GOLDEN A","51.299","-116.982","BC","4.7","0","-0.3","15.5","0","-6.5","0","12.8","0","459.0","49.6","0","142.0","0.0","11","","",NA,"413.7","0.0","1173210" 247 | "GOLDEN AIRPORT","51.300","-116.984","BC","4.4","0",NA,"16.4","0","-6.3","0","",,NA,"34.2","0",NA,"","8","",,NA,"422.4","0.0","1173220" 248 | "GOLDSTREAM RIVER","51.630","-118.425","BC","4.4","0","-0.2","15.0","0","-3.0","0","6.6","0","72.0","105.6","0","100.0","0.0","19","","",NA,"421.5","0.0","1173242" 249 | "MICA DAM","52.053","-118.585","BC","4.8","3","-0.4","14.0","2","-3.0","1","11.0","2",NA,"207.0","2",NA,"0.0","16","","",NA,"369.3","0.0","1175122" 250 | "REVELSTOKE A","50.967","-118.183","BC","6.7","7",NA,"16.9","7","-2.3","6","",,NA,"55.6","7",NA,"","9","",,NA,"271.5","0.0","1176745" 251 | "REVELSTOKE AIRPORT AUTO","50.958","-118.176","BC","6.6","0",NA,"16.7","0","-2.9","0","",,NA,"59.4","0",NA,"0.0","13","",,NA,"354.7","0.0","1176755" 252 | "YOHO PARK","51.443","-116.345","BC","0.8","1",NA,"15.4","1","-11.9","0","",,NA,"84.7","1",NA,"7.0","13","",,NA,"515.0","0.0","11790J1" 253 | "CHETWYND A","55.687","-121.627","BC","4.9","0","0.9","20.5","0","-7.0","0","19.0","0","99.0","75.6","0","260.0","0.0","8","","",NA,"405.2","0.0","1181508" 254 | "DAWSON CREEK A","55.742","-120.183","BC","5.1","4",NA,"21.9","4","-10.3","4","",,NA,"19.3","12",NA,"","1","",,NA,"347.1","0.0","1182289" 255 | "FORT ST. JOHN A","56.238","-120.740","BC","3.7","0",NA,"20.0","0","-8.3","0","59.3","0",NA,"79.6","0",NA,"0.0","9","",,NA,"441.9","0.0","1183001" 256 | "MACKENZIE","55.299","-123.133","BC","3.7","8",NA,"16.4","8","-5.8","8","",,NA,"55.2","8",NA,"","7","",,NA,"327.8","0.0","1184791" 257 | "MACKENZIE AIRPORT AUTO","55.305","-123.138","BC","3.8","0",NA,"16.6","0","-5.9","0","",,NA,"57.6","0",NA,"","10","",,NA,"439.7","0.0","1184793" 258 | "DEASE LAKE A","58.422","-130.031","BC","0.7","12",NA,"12.6","12","-8.1","12","",,NA,"9.9","12",NA,"","2","",,NA,"328.2","0.0","1192341" 259 | "FORT NELSON A","58.836","-122.597","BC","2.9","0",NA,"21.5","0","-7.8","0","15.7","0",NA,"49.1","0",NA,"1.0","10","",,NA,"466.6","0.0","1192946" 260 | "FORT NELSON","58.841","-122.574","BC","3.3","0",NA,"22.2","0","-6.2","0","",,NA,"21.6","0",NA,"0.0","7","",,NA,"454.4","0.0","1192948" 261 | "DEASE LAKE (AUT)","58.426","-130.025","BC","0.8","0",NA,"15.8","0","-8.5","0","",,NA,"25.1","0",NA,"3.0","9","",,NA,"533.8","0.0","119BLM0" 262 | "ATLIN","59.567","-133.700","BC","3.4","0","0.8","16.0","0","-6.5","0","0.0","0","0.0","5.2","0","14.0","0.0","2","","",NA,"453.0","0.0","1200560" 263 | "PLEASANT CAMP","59.450","-136.367","BC","3.0","0","0.1","13.5","0","-5.0","0","4.0","0","11.0","101.6","0","54.0","0.0","16","","",NA,"465.7","0.0","1206197" 264 | -------------------------------------------------------------------------------- /data/eng-climate-summaries-British Columbia-12,2017.csv: -------------------------------------------------------------------------------- 1 | "Environment and Climate Change Canada" 2 | "Monthly Values for December - 2017" 3 | 4 | "Legend" 5 | "Stn_Name","Station Name" 6 | "Lat","Latitude (North + , degrees)" 7 | "Long","Longitude (West - , degrees)" 8 | "Prov","Province" 9 | "Tm","Mean Temperature (°C)" 10 | "DwTm","Days without Valid Mean Temperature" 11 | "D","Mean Temperature difference from Normal (1981-2010) (°C)" 12 | "Tx","Highest Monthly Maximum Temperature (°C)" 13 | "DwTx","Days without Valid Maximum Temperature" 14 | "Tn","Lowest Monthly Minimum Temperature (°C)" 15 | "DwTn","Days without Valid Minimum Temperature" 16 | "S","Snowfall (cm)" 17 | "DwS","Days without Valid Snowfall" 18 | "S%N","Percent of Normal (1981-2010) Snowfall" 19 | "P","Total Precipitation (mm)" 20 | "DwP","Days without Valid Precipitation" 21 | "P%N","Percent of Normal (1981-2010) Precipitation" 22 | "S_G","Snow on the ground at the end of the month (cm)" 23 | "Pd","Number of days with Precipitation 1.0 mm or more" 24 | "BS","Bright Sunshine (hours)" 25 | "DwBS","Days without Valid Bright Sunshine" 26 | "BS%","Percent of Normal (1981-2010) Bright Sunshine" 27 | "HDD","Degree Days below 18 °C" 28 | "CDD","Degree Days above 18 °C" 29 | "Clim_ID","Climate Identifier" 30 | "NA","Not Available" 31 | 32 | "Stn_Name","Lat","Long","Prov","Tm","DwTm","D","Tx","DwTx","Tn","DwTn","S","DwS","S%N","P","DwP","P%N","S_G","Pd","BS","DwBS","BS%","HDD","CDD","Clim_ID" 33 | "CHEMAINUS","48.935","-123.742","BC","3.0","0",NA,"8.0","0","-3.5","0","34.0","0",NA,"175.4","0",NA,"1.0","10","","",NA,"463.6","0.0","1011500" 34 | "COWICHAN LAKE FORESTRY","48.824","-124.133","BC","1.1","0","-1.8","11.0","0","-8.5","0","18.8","0","95.0","135.6","0","40.0","6.0","12","","",NA,"523.7","0.0","1012040" 35 | "LAKE COWICHAN","48.829","-124.052","BC","1.7","17","-0.9","10.5","13","-8.0","12","23.4","27",NA,"119.6","19",NA,"","8","","",NA,"228.9","0.0","1012055" 36 | "DISCOVERY ISLAND","48.425","-123.226","BC","",,NA,"10.0","0","",,"",,NA,"",,NA,"","","",,NA,"","","1012475" 37 | "ESQUIMALT HARBOUR","48.432","-123.439","BC","4.9","0",NA,"10.8","0","-0.6","0","",,NA,"105.8","3",NA,"","8","",,NA,"404.7","0.0","1012710" 38 | "GALIANO NORTH","48.985","-123.573","BC","4.7","11",NA,"9.0","11","0.5","11","5.0","11",NA,"98.2","11",NA,"0.0","7","","",NA,"266.4","0.0","10130MN" 39 | "MALAHAT","48.575","-123.530","BC","2.5","0",NA,"9.1","0","-5.1","0","",,NA,"70.8","15",NA,"","7","",,NA,"479.6","0.0","1014820" 40 | "METCHOSIN","48.374","-123.561","BC","",,NA,"",,"",,"29.0","5",NA,"109.0","5",NA,"","9","","",NA,"","","1015105" 41 | "NORTH COWICHAN","48.824","-123.718","BC","",,NA,"",,"",,"15.8","0","167.0","139.6","0","79.0","0.0","12","","",NA,"","","1015628" 42 | "NORTH COWICHAN","48.824","-123.719","BC","2.4","0",NA,"11.0","0","-7.9","0","",,NA,"47.2","13",NA,"0.0","5","",,NA,"482.7","0.0","1015630" 43 | "NORTH PENDER ISLAND","48.764","-123.287","BC","3.8","3",NA,"9.5","3","-2.5","3","3.0","3",NA,"115.0","3",NA,"0.0","11","","",NA,"396.4","0.0","1015638" 44 | "RACE ROCKS","48.298","-123.531","BC","5.8","0",NA,"12.1","0","-0.1","0","",,NA,"",,NA,"","","",,NA,"379.3","0.0","1016640" 45 | "SAANICHTON CDA","48.622","-123.419","BC","3.6","10","-0.8","10.5","6","-3.0","6","4.0","6",NA,"120.2","6",NA,"0.0","11","","",NA,"301.8","0.0","1016940" 46 | "SALTSPRING ST MARY'S L","48.888","-123.546","BC","3.4","2","-0.8","8.0","2","-3.0","2","7.8","2",NA,"108.2","2",NA,"0.0","9","","",NA,"424.6","0.0","1016995" 47 | "SAANICHTON MT NEWTON","48.598","-123.427","BC","",,NA,"",,"",,"5.6","23",NA,"89.2","23",NA,"0.0","8","","",NA,"","","1016RM0" 48 | "SATURNA CAPMON CS","48.775","-123.128","BC","2.9","0",NA,"8.3","0","-2.4","0","",,NA,"151.8","0",NA,"0.0","11","",,NA,"466.9","0.0","1017099" 49 | "SATURNA ISLAND CS","48.784","-123.045","BC","4.5","0",NA,"9.4","0","0.3","0","",,NA,"112.0","2",NA,"","9","",,NA,"417.1","0.0","1017101" 50 | "SHAWNIGAN LAKE","48.647","-123.626","BC","2.7","0","-0.3","10.5","0","-6.0","0","37.0","0","248.0","117.2","0","60.0","10.0","11","","",NA,"474.2","0.0","1017230" 51 | "SHERINGHAM POINT","48.377","-123.921","BC","5.9","0",NA,"12.0","0","-0.3","0","",,NA,"142.8","2",NA,"","11","",,NA,"374.2","0.0","1017254" 52 | "VICTORIA UNIVERSITY CS","48.457","-123.305","BC","4.2","0",NA,"9.4","0","-2.3","0","",,NA,"122.9","0",NA,"","12","",,NA,"426.9","0.0","1018598" 53 | "VICTORIA FRANCIS PARK","48.476","-123.443","BC","",,NA,"",,"",,"21.6","3",NA,"132.8","3",NA,"","11","","",NA,"","","1018605" 54 | "VICTORIA GONZALES CS","48.413","-123.325","BC","4.7","0",NA,"10.1","0","-1.5","0","",,NA,"102.6","4",NA,"","9","",,NA,"412.7","0.0","1018611" 55 | "VICTORIA INTL A","48.647","-123.426","BC","3.3","0",NA,"11.3","0","-4.4","0","10.1","0",NA,"131.3","0",NA,"","12","",,NA,"454.3","0.0","1018621" 56 | "WILLIAM HEAD","48.340","-123.539","BC","5.9","2","0.5","11.0","2","0.0","2","1.0","2",NA,"85.4","2",NA,"0.0","11","","",NA,"350.9","0.0","1018935" 57 | "BALLENAS ISLAND","49.350","-124.160","BC","4.2","0",NA,"8.7","0","-0.7","0","",,NA,"61.2","3",NA,"","9","",,NA,"427.6","0.0","1020590" 58 | "CAMPBELL RIVER A","49.952","-125.273","BC","0.8","2","-1.3","9.0","2","-10.5","2","33.8","2",NA,"107.8","2",NA,"0.0","12","","",NA,"498.6","0.0","1021261" 59 | "CAPE MUDGE","49.998","-125.195","BC","3.2","0","-0.6","10.0","0","-2.5","0","16.4","0","112.0","97.8","0","42.0","2.0","12","","",NA,"460.3","0.0","1021330" 60 | "CHROME ISLAND","49.472","-124.683","BC","3.6","0",NA,"10.0","0","-2.0","0","11.2","0",NA,"94.4","0",NA,"0.0","11","","",NA,"447.0","0.0","1021500" 61 | "COMOX A","49.717","-124.900","BC","2.4","0","-1.0","8.9","0","-5.2","0","11.4","0","61.0","91.2","0","49.0","2.0","11","",,NA,"482.1","0.0","1021830" 62 | "CORTES ISLAND TIBER BAY","50.071","-124.949","BC","1.6","0",NA,"9.5","0","-6.5","0","11.2","0",NA,"91.3","0",NA,"10.0","12","","",NA,"506.9","0.0","1021960" 63 | "COURTENAY PUNTLEDGE","49.686","-125.033","BC","1.9","20",NA,"8.0","20","-3.0","19","0.0","20",NA,"14.2","20",NA,"","2","","",NA,"176.7","0.0","1021989" 64 | "ENTRANCE ISLAND","49.209","-123.811","BC","3.8","9",NA,"8.4","9","-0.2","8","",,NA,"30.0","12",NA,"","4","",,NA,"311.4","0.0","1022689" 65 | "FANNY ISLAND","50.454","-125.993","BC","4.1","0",NA,"10.7","0","-2.8","0","",,NA,"73.2","6",NA,"","10","",,NA,"430.7","0.0","1022795" 66 | "HERIOT BAY SE","50.099","-125.203","BC","2.2","4",NA,"8.0","4","-4.0","4","17.2","4",NA,"59.4","4",NA,"10.0","7","","",NA,"427.0","0.0","1023462" 67 | "LITTLE QUALICUM HATCHERY","49.353","-124.512","BC","0.7","18","-2.3","7.0","18","-7.5","18","9.0","18",NA,"24.0","18",NA,"","4","","",NA,"225.2","0.0","1024638" 68 | "NANAIMO A","49.054","-123.870","BC","1.8","2",NA,"10.0","2","-7.5","2","40.8","2",NA,"111.6","2",NA,"9.0","9","","",NA,"469.3","0.0","1025369" 69 | "NANAIMO CITY YARD","49.199","-123.988","BC","",,NA,"",,"",,"4.2","0","44.0","74.7","0","42.0","0.0","9","","",NA,"","","10253G0" 70 | "PINE ISLAND","50.976","-127.728","BC","5.9","1","0.2","12.5","1","1.5","1","0.0","1",NA,"115.6","1",NA,"0.0","14","","",NA,"362.3","0.0","1026170" 71 | "PORT HARDY A","50.681","-127.367","BC","3.4","0",NA,"13.3","0","-5.0","0","12.4","1",NA,"95.4","0",NA,"","19","",,NA,"453.0","0.0","1026271" 72 | "QUALICUM BEACH AIRPORT","49.337","-124.394","BC","2.0","0",NA,"9.1","0","-6.5","0","",,NA,"113.7","0",NA,"","10","",,NA,"496.4","0.0","1026562" 73 | "QUALICUM R FISH RESEARCH","49.394","-124.617","BC","2.7","6","-0.7","9.0","6","-4.5","6","9.6","6",NA,"94.3","6",NA,"0.0","11","","",NA,"382.3","0.0","1026565" 74 | "QUINSAM RIVER HATCHERY","50.016","-125.304","BC","1.4","1","-1.2","9.0","1","-6.5","1","18.6","1",NA,"70.0","1",NA,"","10","","",NA,"498.7","0.0","1026639" 75 | "SISTERS ISLAND","49.487","-124.435","BC","4.7","0",NA,"11.4","0","-0.1","0","",,NA,"",,NA,"","","",,NA,"413.6","0.0","1027403" 76 | "ENTRANCE ISLAND","49.209","-123.809","BC","4.4","4",NA,"8.5","4","-0.5","4","0.0","4",NA,"80.2","4",NA,"","8","","",NA,"368.5","0.0","102BFHH" 77 | "CAPE BEALE LIGHT","48.786","-125.216","BC","5.9","0","0.1","13.0","0","-1.0","0","1.0","0","27.0","183.2","0","48.0","0.0","12","","",NA,"373.8","0.0","1031316" 78 | "ESTEVAN POINT","49.383","-126.543","BC","5.9","0","0.3","14.0","0","-2.0","0","0.0","0","0.0","130.6","0","30.0","0.0","14","","",NA,"374.5","0.0","1032730" 79 | "ESTEVAN POINT CS","49.383","-126.543","BC","5.5","0",NA,"13.1","0","-2.0","0","",,NA,"120.8","0",NA,"","13","",,NA,"389.0","0.0","1032731" 80 | "LENNARD ISLAND","49.111","-125.923","BC","5.5","0",NA,"13.5","0","-1.5","0","1.0","0","28.0","128.8","0","30.0","0.0","13","","",NA,"386.4","0.0","1034600" 81 | "NITINAT RIVER HATCHERY","48.859","-124.655","BC","2.8","1","-0.5","10.0","1","-5.0","1","4.0","1",NA,"231.7","1",NA,"","12","","",NA,"455.8","0.0","1035612" 82 | "NOOTKA LIGHTSTATION","49.600","-126.617","BC","5.8","1","0.5","14.5","1","1.5","1","0.0","1",NA,"124.8","1",NA,"","12","","",NA,"365.7","0.0","1035614" 83 | "PACHENA POINT","48.723","-125.097","BC","5.6","1","0.3","10.5","1","-1.0","1","3.8","1",NA,"204.0","1",NA,"0.0","11","","",NA,"372.6","0.0","1035940" 84 | "QUATSINO","50.534","-127.653","BC","3.8","1","-0.2","12.5","1","-2.5","1","3.2","1",NA,"120.4","1",NA,"0.0","17","","",NA,"426.9","0.0","1036570" 85 | "PORT ALBERNI (AUT)","49.317","-124.927","BC","1.1","6",NA,"6.1","6","-6.2","5","",,NA,"84.2","6",NA,"0.0","9","",,NA,"422.0","0.0","1036B06" 86 | "SARTINE ISLAND (AUT)","50.821","-128.908","BC","6.4","4",NA,"12.1","4","1.4","0","",,NA,"116.6","4",NA,"","17","",,NA,"311.9","0.0","1037090" 87 | "SOLANDER ISLAND (AUT)","50.112","-127.940","BC","6.5","4",NA,"13.5","4","1.8","0","",,NA,"93.8","4",NA,"","14","",,NA,"310.7","0.0","1037553" 88 | "TAHSIS VILLAGE NORTH","49.932","-126.654","BC","3.8","13",NA,"10.0","13","-2.0","13","",,NA,"64.8","25",NA,"","5","","",NA,"255.0","0.0","1037899" 89 | "TOFINO A","49.082","-125.773","BC","4.5","0","-0.5","13.5","0","-3.5","0","0.0","0","0.0","145.8","0","33.0","0.0","11","","",NA,"418.3","0.0","1038205" 90 | "UCLUELET KENNEDY CAMP","48.945","-125.527","BC","5.0","0","-0.5","15.0","0","-4.0","0","0.0","0","0.0","186.1","0","41.0","0.0","15","","",NA,"403.2","0.0","1038332" 91 | "ZEBALLOS MURAUDE CREEK","50.053","-126.779","BC","3.4","0",NA,"16.5","0","-5.0","0","0.0","0",NA,"105.1","0",NA,"0.0","10","","",NA,"451.8","0.0","1039035" 92 | "BOWEN ISLAND SUNSET PARK","49.360","-123.402","BC","",,NA,"",,"",,"13.0","25",NA,"89.0","25",NA,"","6","","",NA,"","","104091B" 93 | "GIBSONS GOWER POINT","49.386","-123.541","BC","3.7","2","-0.5","9.0","2","-2.0","2","0.8","2",NA,"99.4","2",NA,"0.0","7","","",NA,"415.2","0.0","1043152" 94 | "MERRY ISLAND LIGHTSTATION","49.468","-123.913","BC","4.2","0","-1.0","8.0","0","0.0","0","7.8","0","104.0","101.6","0","76.0","0.0","10","","",NA,"429.2","0.0","1045100" 95 | "HOWE SOUND - PAM ROCKS","49.488","-123.299","BC","4.7","0",NA,"10.9","0","-0.2","0","",,NA,"69.0","2",NA,"","9","",,NA,"413.2","0.0","10459NN" 96 | "PENDER HARBOUR","49.634","-124.032","BC","",,NA,"",,"",,"14.2","0",NA,"101.2","0",NA,"3.0","12","","",NA,"","","1046115" 97 | "PORT MELLON","49.526","-123.496","BC","2.9","0",NA,"10.1","0","-4.2","0","",,NA,"222.5","0",NA,"5.0","10","",,NA,"467.0","0.0","1046332" 98 | "POWELL RIVER A","49.834","-124.500","BC","1.4","0","-1.8","7.5","0","-7.0","0","18.0","0","157.0","98.9","0","63.0","10.0","11","","",NA,"515.9","0.0","1046391" 99 | "POWELL RIVER","49.835","-124.497","BC","1.5","0",NA,"7.8","0","-6.6","0","",,NA,"",,NA,"5.0","","",,NA,"510.0","0.0","1046392" 100 | "SECHELT AUT","49.458","-123.715","BC","2.2","0",NA,"8.6","0","-4.8","0","",,NA,"120.7","0",NA,"2.0","10","",,NA,"490.9","0.0","1047172" 101 | "SQUAMISH AIRPORT","49.783","-123.161","BC","1.6","0",NA,"11.3","0","-6.5","0","",,NA,"141.7","0",NA,"44.0","8","",,NA,"509.3","0.0","10476F0" 102 | "WHISTLER","50.129","-122.955","BC","-3.7","0","-0.9","4.0","0","-13.0","0","82.4","0","72.0","76.7","0","50.0","72.0","10","","",NA,"674.1","0.0","1048898" 103 | "CAPE ST JAMES","51.936","-131.016","BC","5.9","12",NA,"10.3","12","0.7","0","",,NA,"",,NA,"","","",,NA,"230.7","0.0","1051351" 104 | "KINDAKUN ROCKS (AUT)","53.316","-132.772","BC","6.3","4",NA,"15.7","4","-0.8","0","",,NA,"88.2","6",NA,"","13","",,NA,"315.8","0.0","1054222" 105 | "LANGARA","54.255","-133.058","BC","4.7","0","0.4","10.5","0","-3.5","0","5.4","0","45.0","119.6","0","54.0","1.0","19","",,NA,"411.5","0.0","1054500" 106 | "ROSE SPIT (AUT)","54.159","-131.661","BC","4.5","0",NA,"10.4","0","-4.7","0","",,NA,"69.8","4",NA,"","16","",,NA,"417.3","0.0","1056869" 107 | "SANDSPIT AIRPORT AUTO","53.249","-131.813","BC","4.4","1",NA,"10.9","1","-2.6","0","",,NA,"47.3","1",NA,"","11","",,NA,"408.0","0.0","1057051" 108 | "SANDSPIT","53.254","-131.814","BC","4.9","15",NA,"9.9","15","-0.9","15","",,NA,"26.8","15",NA,"","7","",,NA,"210.4","0.0","1057052" 109 | "ADDENBROKE ISLAND","51.604","-127.864","BC","4.5","0","-0.2","17.5","0","-3.0","0","5.0","0","34.0","126.6","0","34.0","0.0","15","","",NA,"419.8","0.0","1060080" 110 | "BELLA BELLA","52.185","-128.157","BC","1.5","9",NA,"11.1","9","-12.8","9","",,NA,"132.1","9",NA,"","11","",,NA,"363.8","0.0","1060815" 111 | "BELLA COOLA AIRPORT","52.389","-126.587","BC","-1.6","1",NA,"8.7","1","-12.4","0","",,NA,"40.0","1",NA,"5.0","9","",,NA,"588.7","0.0","1060844" 112 | "BOAT BLUFF","52.643","-128.524","BC","3.8","0","0.2","15.5","0","-4.0","0","21.2","0","97.0","253.2","0","40.0","12.0","16","","",NA,"439.5","0.0","1060901" 113 | "BONILLA ISLAND","53.493","-130.638","BC","5.6","0","0.3","15.0","0","-2.5","0","8.8","0","85.0","164.6","0","61.0","1.0","20","","",NA,"385.6","0.0","1060902" 114 | "BONILLA ISLAND (AUT)","53.493","-130.639","BC","5.3","4",NA,"15.2","4","-2.5","0","",,NA,"87.4","4",NA,"","13","",,NA,"342.3","0.0","1060R0K" 115 | "CATHEDRAL POINT (AUT)","52.187","-127.471","BC","2.3","4",NA,"11.0","4","-5.5","0","",,NA,"109.6","14",NA,"","9","",,NA,"422.9","0.0","1061458" 116 | "CUMSHEWA ISLAND","53.030","-131.602","BC","5.5","4",NA,"10.7","4","-1.7","0","",,NA,"12.4","4",NA,"","5","",,NA,"338.0","0.0","1062251" 117 | "DRYAD POINT","52.185","-128.112","BC","4.2","0","-0.2","16.5","0","-3.0","0","21.0","0","198.0","131.6","0","48.0","0.0","15","","",NA,"426.5","0.0","1062544" 118 | "EGG ISLAND","51.247","-127.835","BC","6.5","19","1.8","16.0","19","1.0","19","0.0","19",NA,"24.0","19",NA,"","4","","",NA,"138.1","0.0","1062646" 119 | "GREY ISLET (AUT)","54.580","-130.698","BC","3.5","4",NA,"12.8","4","-5.1","0","",,NA,"92.4","13",NA,"","14","",,NA,"391.3","0.0","1063303" 120 | "HERBERT ISLAND (AUT)","50.940","-127.632","BC","6.1","0",NA,"12.3","0","1.3","0","",,NA,"70.6","0",NA,"","12","",,NA,"370.3","0.0","1063461" 121 | "HOLLAND ROCK","54.172","-130.361","BC","4.6","0",NA,"15.4","0","-3.8","0","",,NA,"54.2","10",NA,"","10","",,NA,"413.9","0.0","1063496" 122 | "IVORY ISLAND","52.270","-128.407","BC","4.3","0","-0.6","14.5","0","-4.0","0","17.2","0","115.0","127.0","0","39.0","9.0","14","","",NA,"425.1","0.0","1063690" 123 | "KEMANO","53.563","-127.943","BC","-2.2","0","-1.4","4.5","0","-14.0","0","13.6","0","21.0","73.5","0","26.0","20.0","11","","",NA,"625.9","0.0","1064020" 124 | "KITIMAT TOWNSITE","54.054","-128.634","BC","-0.6","18","0.2","5.0","18","-17.0","6","4.0","6",NA,"89.0","6",NA,"0.0","13","","",NA,"241.8","0.0","1064320" 125 | "KITIMAT 2","54.010","-128.705","BC","-2.2","7","-2.0","8.0","7","-15.0","7","1.0","7",NA,"89.3","7",NA,"0.0","10","","",NA,"484.6","0.0","1064321" 126 | "LUCY ISLAND LIGHTSTATION","54.296","-130.609","BC","4.8","0",NA,"14.7","0","-4.1","0","",,NA,"",,NA,"","","",,NA,"410.2","0.0","1064728" 127 | "MCINNES ISLAND","52.262","-128.719","BC","5.4","0","0.4","16.0","0","-2.0","0","3.0","0","28.0","139.6","0","48.0","0.0","17","",,NA,"391.1","0.0","1065010" 128 | "PRINCE RUPERT","54.286","-130.445","BC","2.3","9",NA,"13.9","9","-9.6","9","",,NA,"76.1","9",NA,"","9","",,NA,"345.2","0.0","1066482" 129 | "PRINCE RUPERT MONT CIRC","54.320","-130.290","BC","",,NA,"",,"",,"4.0","23",NA,"91.6","23",NA,"","6","","",NA,"","","1066488" 130 | "TERRACE PCC","54.502","-128.625","BC","-1.8","2","-0.4","4.5","2","-14.5","2","4.0","2",NA,"28.4","2",NA,"3.0","7","","",NA,"573.5","0.0","1068131" 131 | "TERRACE A","54.469","-128.578","BC","-3.8","0",NA,"4.2","0","-15.3","0","9.2","0",NA,"31.3","0",NA,"0.0","9","",,NA,"675.3","0.0","1068134" 132 | "TRIPLE ISLAND","54.295","-130.880","BC","5.2","0",NA,"15.0","0","-4.0","0","0.0","0",NA,"61.2","0",NA,"0.0","13","","",NA,"395.8","0.0","1068250" 133 | "EQUITY SILVER","54.199","-126.277","BC","-10.2","0","-2.7","5.5","0","-30.0","0","22.8","0","41.0","22.8","0","40.0","0.0","7","","",NA,"874.1","0.0","1072692" 134 | "HOUSTON","54.396","-126.668","BC","-10.3","8",NA,"3.0","8","-28.0","8","4.0","17",NA,"4.0","17",NA,"33.0","2","","",NA,"650.7","0.0","1073615" 135 | "SMITHERS","54.825","-127.183","BC","-12.3","11",NA,"1.3","10","-28.8","11","",,NA,"1.4","10",NA,"","0","",,NA,"606.1","0.0","1077499" 136 | "SMITHERS A","54.825","-127.183","BC","-9.2","0","-2.0","2.0","0","-29.5","0","15.4","0","34.0","9.2","0","22.0","36.0","5","","",NA,"842.7","0.0","1077500" 137 | "SMITHERS AIRPORT AUTO","54.824","-127.189","BC","-10.1","0",NA,"1.4","0","-30.9","0","",,NA,"1.6","30",NA,"33.0","1","",,NA,"870.2","0.0","1077501" 138 | "SUSKWA VALLEY","55.289","-127.171","BC","-9.2","1","-4.1","1.5","1","-24.5","1","22.6","1",NA,"25.8","1",NA,"34.0","8","","",NA,"817.2","0.0","107G879" 139 | "OOTSA LAKESKINS LAKE CLIMATE","53.772","-125.997","BC","-7.4","0",NA,"5.7","0","-23.8","0","",,NA,"7.5","0",NA,"23.0","2","",,NA,"787.3","0.0","1085836" 140 | "PEMBERTON AIRPORT CS","50.306","-122.734","BC","-2.6","0",NA,"5.5","0","-12.6","0","",,NA,"57.3","0",NA,"24.0","9","",,NA,"638.3","0.0","1086082" 141 | "PUNTZI MOUNTAIN (AUT)","52.114","-124.136","BC","-11.8","0",NA,"4.2","0","-33.5","0","",,NA,"12.3","0",NA,"19.0","4","",,NA,"924.5","0.0","1086558" 142 | "TATLAYOKO LAKE RCS","51.675","-124.403","BC","-8.4","0",NA,"6.4","0","-27.3","0","",,NA,"13.4","0",NA,"17.0","5","",,NA,"818.9","0.0","1088015" 143 | "BURNS LAKE DECKER LAKE","54.383","-125.959","BC","-12.1","0",NA,"2.6","0","-33.9","0","",,NA,"4.2","0",NA,"34.0","2","",,NA,"934.0","0.0","1091174" 144 | "FORT ST JAMES","54.455","-124.286","BC","-6.8","17","1.0","3.0","17","-26.5","17","0.0","17",NA,"0.6","17",NA,"","0","","",NA,"346.7","0.0","1092970" 145 | "FORT ST JAMES AUTO","54.455","-124.286","BC","-8.9","0",NA,"3.9","0","-28.2","0","",,NA,"1.2","0",NA,"17.0","0","",,NA,"834.2","0.0","1092975" 146 | "MCLEESE LAKE GRANITE MT","52.531","-122.286","BC","-6.2","22",NA,"6.0","17","-27.0","16","22.8","17",NA,"22.8","17",NA,"","5","","",NA,"218.0","0.0","1095018" 147 | "PRINCE GEORGE","53.884","-122.678","BC","-9.8","7",NA,"4.0","7","-33.0","7","",,NA,"6.7","7",NA,"","2","",,NA,"667.2","0.0","1096439" 148 | "PRINCE GEORGE AIRPORT AUTO","53.889","-122.672","BC","-10.0","0",NA,"4.2","0","-32.8","0","",,NA,"12.7","0",NA,"14.0","3","",,NA,"868.0","0.0","1096453" 149 | "PRINCE GEORGE STP","53.880","-122.768","BC","-18.1","26","-12.3","4.5","6","-28.0","26","21.0","5",NA,"23.4","5",NA,"","5","","",NA,"180.5","0.0","1096468" 150 | "QUESNEL","53.026","-122.510","BC","-7.7","4",NA,"4.8","4","-27.6","4","",,NA,"0.0","4",NA,"","0","",,NA,"692.6","0.0","1096629" 151 | "QUESNEL AIRPORT AUTO","53.027","-122.506","BC","-8.6","0",NA,"4.9","0","-29.4","0","",,NA,"21.4","0",NA,"21.0","4","",,NA,"824.4","0.0","1096631" 152 | "SPOKIN LAKE 4E","52.184","-121.686","BC","-11.0","0","-3.2","7.0","0","-35.0","0","54.0","0","116.0","54.0","0","110.0","30.0","9","","",NA,"897.7","0.0","1097646" 153 | "WILLIAMS LAKE A","52.183","-122.054","BC","-9.3","1",NA,"4.7","1","-26.8","0","43.0","0",NA,"32.0","0",NA,"","7","",,NA,"817.9","0.0","1098941" 154 | "VANDERHOOF","54.033","-124.017","BC","-10.2","0","-2.0","4.5","0","-31.0","0","1.4","0","4.0","3.2","0","8.0","0.0","1","","",NA,"873.2","0.0","1098D90" 155 | "108 MILE HOUSE ABEL LAKE","51.623","-121.263","BC","-7.9","0",NA,"4.5","0","-29.5","0","76.0","0",NA,"76.0","0",NA,"55.0","12","","",NA,"803.9","0.0","109E7R6" 156 | "ABBOTSFORD A","49.025","-122.360","BC","1.7","0",NA,"10.3","0","-6.1","0","7.8","0",NA,"199.6","0",NA,"2.0","11","",,NA,"506.6","0.0","1100031" 157 | "AGASSIZ RCS","49.243","-121.760","BC","2.5","0","-1.1","11.7","0","-6.3","0","",,NA,"189.1","7",NA,"39.0","16","",,NA,"480.2","0.0","1100119" 158 | "AGASSIZ CDA","49.243","-121.760","BC","4.8","12","1.6","11.0","11","-2.0","10","0.0","11",NA,"135.4","11",NA,"","10","","",NA,"250.7","0.0","1100120" 159 | "WHISTLER - NESTERS","50.129","-122.955","BC","-3.6","0",NA,"4.7","0","-13.0","0","",,NA,"57.6","0",NA,"55.0","9","",,NA,"669.4","0.0","1100875" 160 | "BLACKCOMB BASE SLIDING CENTER","50.102","-122.936","BC","-3.3","0",NA,"6.2","0","-13.4","0","",,NA,"74.6","0",NA,"92.0","9","",,NA,"659.0","0.0","1100881" 161 | "BURNABY SIMON FRASER U","49.278","-122.918","BC","2.0","30","-0.9","3.0","30","1.0","30","0.0","30",NA,"0.4","30",NA,"","0","","",NA,"16.0","0.0","1101158" 162 | "CALLAGHAN VALLEY","50.144","-123.111","BC","-2.2","0",NA,"7.5","0","-14.1","0","",,NA,"127.7","0",NA,"128.0","10","",,NA,"626.1","0.0","1101300" 163 | "CLOVERDALE EAST","49.109","-122.698","BC","2.2","0",NA,"9.0","0","-4.5","0","23.8","0",NA,"207.0","0",NA,"1.0","11","","",NA,"488.3","0.0","1101708" 164 | "DELTA BURNS BOG","49.126","-123.002","BC","1.9","0",NA,"8.8","0","-8.6","0","",,NA,"194.3","0",NA,"","10","",,NA,"498.8","0.0","1102415" 165 | "DELTA TSAWWASSEN BEACH","49.011","-123.093","BC","2.3","0","-2.7","9.5","0","-6.5","0","0.0","0","0.0","173.1","0","138.0","0.0","11","","",NA,"485.9","0.0","1102425" 166 | "FORT LANGLEY TELEGRAPH TRAIL","49.145","-122.551","BC","1.7","0",NA,"10.0","0","-6.0","0","14.8","0",NA,"212.0","0",NA,"0.0","11","","",NA,"504.1","0.0","1102912" 167 | "MISSION WEST ABBEY","49.153","-122.271","BC","1.8","0","-0.9","11.0","0","-6.5","0","30.0","0","148.0","237.2","0","112.0","18.0","12","","",NA,"500.7","0.0","1105192" 168 | "RICHMOND OPERATIONS CENTRE","49.182","-123.078","BC","",,NA,"",,"",,"",,NA,"243.9","0",NA,"","20","",,NA,"","","1105210" 169 | "N VANC GROUSE MTN RESORT","49.381","-123.078","BC","0.6","1","1.6","14.5","1","-10.0","1","136.0","1",NA,"168.0","1",NA,"0.0","11","","",NA,"522.1","0.0","1105658" 170 | "N VANCOUVER WHARVES","49.315","-123.115","BC","",,NA,"",,"",,"0.0","4",NA,"197.0","4",NA,"0.0","10","","",NA,"","","1105669" 171 | "PITT MEADOWS CS","49.208","-122.690","BC","2.0","1",NA,"9.4","1","-6.0","0","",,NA,"244.1","1",NA,"1.0","11","",,NA,"481.0","0.0","1106178" 172 | "POINT ATKINSON","49.330","-123.265","BC","4.1","0",NA,"9.8","0","-1.2","0","",,NA,"148.8","0",NA,"","10","",,NA,"431.3","0.0","1106200" 173 | "RICHMOND DALLYN 2","49.179","-123.087","BC","",,NA,"",,"",,"2.2","24",NA,"311.4","24",NA,"0.0","4","","",NA,"","","1106764" 174 | "PORT MOODY GLENAYRE","49.279","-122.881","BC","2.1","1","-1.2","9.0","1","-6.0","1","0.0","1",NA,"193.0","1",NA,"0.0","8","","",NA,"476.1","0.0","1106CL2" 175 | "RICHMOND NATURE PARK","49.171","-123.093","BC","2.5","0","-0.9","9.0","0","-9.0","0","4.4","0","40.0","178.9","0","107.0","2.0","9","","",NA,"480.3","0.0","1106PF7" 176 | "SANDHEADS CS","49.106","-123.303","BC","3.9","2",NA,"8.9","2","-1.1","0","",,NA,"",,NA,"","","",,NA,"408.5","0.0","1107010" 177 | "SUMAS CANAL","49.113","-122.110","BC","3.5","20",NA,"12.0","15","-5.0","14","8.0","15",NA,"174.2","15",NA,"","8","","",NA,"159.0","0.0","1107785" 178 | "VANCOUVER SEA ISLAND CCG","49.183","-123.187","BC","2.7","0",NA,"9.5","0","-4.9","0","",,NA,"155.6","0",NA,"","10","",,NA,"473.1","0.0","1108380" 179 | "VANCOUVER INTL A","49.195","-123.184","BC","2.6","0",NA,"8.9","0","-5.8","0","1.2","0",NA,"170.6","0",NA,"","10","",,NA,"478.8","0.0","1108395" 180 | "VANCOUVER HARBOUR CS","49.295","-123.122","BC","4.0","0",NA,"9.3","0","-2.5","0","",,NA,"187.3","0",NA,"","10","",,NA,"434.7","0.0","1108446" 181 | "WEST VANCOUVER AUT","49.347","-123.193","BC","3.0","0",NA,"10.0","0","-4.4","0","",,NA,"",,NA,"","","",,NA,"465.1","0.0","1108824" 182 | "WHISTLER ROUNDHOUSE","50.068","-122.947","BC","-2.5","5",NA,"11.5","5","-16.5","5","92.0","5",NA,"92.0","5",NA,"193.0","11","","",NA,"533.2","0.0","1108906" 183 | "WHITE ROCK CAMPBELL SCIENTIFIC","49.018","-122.784","BC","3.4","0",NA,"10.9","0","-3.0","0","",,NA,"0.0","27",NA,"","0","",,NA,"452.5","0.0","1108910" 184 | "HOPE A","49.368","-121.498","BC","0.8","4",NA,"9.2","4","-8.3","4","",,NA,"143.2","4",NA,"","10","",,NA,"465.4","0.0","1113542" 185 | "HOPE AIRPORT","49.370","-121.493","BC","0.9","0",NA,"9.8","0","-8.3","0","",,NA,"108.4","0",NA,"42.0","7","",,NA,"530.2","0.0","1113543" 186 | "HOPE SLIDE","49.267","-121.233","BC","-3.5","0","-1.8","3.0","0","-17.0","0","144.0","0","204.0","193.2","0","135.0","76.0","16","","",NA,"667.2","0.0","1113581" 187 | "LILLOOET","50.684","-121.934","BC","-4.0","0",NA,"7.1","0","-19.3","0","",,NA,"",,NA,"","","",,NA,"682.9","0.0","1114619" 188 | "LYTTON A","50.224","-121.582","BC","-3.8","8",NA,"4.8","8","-16.8","8","",,NA,"9.1","8",NA,"","3","",,NA,"500.9","0.0","1114738" 189 | "LYTTON RCS","50.224","-121.582","BC","-3.3","2",NA,"7.2","2","-17.2","1","",,NA,"32.4","3",NA,"18.0","8","",,NA,"618.2","0.0","1114746" 190 | "JELLICOE","49.673","-120.333","BC","-6.8","1",NA,"2.5","1","-25.0","1","81.0","1",NA,"81.0","1",NA,"59.0","14","","",NA,"744.7","0.0","1123721" 191 | "KELOWNA","49.957","-119.378","BC","-3.9","8",NA,"3.3","8","-19.9","8","",,NA,"16.8","8",NA,"","6","",,NA,"502.6","0.0","1123939" 192 | "KELOWNA UBCO","49.941","-119.400","BC","-3.3","0",NA,"4.3","0","-16.3","0","",,NA,"42.6","0",NA,"28.0","8","",,NA,"661.6","0.0","1123996" 193 | "MERRITT","50.113","-120.778","BC","-5.8","0",NA,"8.2","0","-25.8","0","",,NA,"1.0","29",NA,"","1","",,NA,"738.6","0.0","1125073" 194 | "MERRITT STP","50.114","-120.801","BC","-5.1","0","-1.5","7.5","0","-22.0","0","59.2","0","261.0","60.6","0","168.0","0.0","8","","",NA,"716.1","0.0","1125079" 195 | "OKANAGAN CENTRE","50.056","-119.445","BC","-1.7","0","-1.7","5.5","0","-12.5","0","67.4","0","275.0","79.4","0","196.0","29.0","10","","",NA,"610.8","0.0","1125700" 196 | "OLIVER STP","49.179","-119.545","BC","-0.7","13","0.4","5.5","13","-11.0","13","30.2","13",NA,"32.2","13",NA,"","4","","",NA,"336.7","0.0","1125766" 197 | "OSOYOOS CS","49.028","-119.441","BC","-2.0","0","-1.3","5.9","0","-12.8","0","",,NA,"28.9","0",NA,"13.0","5","",,NA,"620.9","0.0","1125852" 198 | "PEACHLAND","49.783","-119.717","BC","-1.4","0","-1.0","5.0","0","-13.0","0","65.0","0","207.0","83.8","0","183.0","35.0","11","","",NA,"602.9","0.0","1126070" 199 | "PENTICTON A","49.463","-119.602","BC","-2.6","0",NA,"5.0","0","-15.2","0","45.5","0",NA,"57.6","0",NA,"33.0","10","",,NA,"639.7","0.0","1126146" 200 | "PRINCETON A","49.468","-120.513","BC","-6.7","0","-1.1","2.0","0","-25.0","0","76.0","0","202.0","80.8","0","222.0","58.0","10","","",NA,"765.5","0.0","1126510" 201 | "VERNON AUTO","50.223","-119.194","BC","-4.4","0",NA,"4.6","0","-18.5","0","",,NA,"27.4","0",NA,"","8","",,NA,"694.9","0.0","1128582" 202 | "VERNON NORTH","50.344","-119.271","BC","-3.8","0","-1.7","5.5","0","-16.5","0","49.2","0","104.0","51.0","0","89.0","26.0","9","","",NA,"677.2","0.0","1128583" 203 | "VERNON SILVER STAR LODGE","50.359","-119.056","BC","-8.0","0",NA,"6.0","0","-23.5","0","115.0","0",NA,"115.0","0",NA,"114.0","13","","",NA,"805.1","0.0","1128584" 204 | "PRINCETON CS","49.465","-120.510","BC","-7.2","0",NA,"2.1","0","-25.9","0","",,NA,"79.0","0",NA,"54.0","10","",,NA,"782.6","0.0","112FN0M" 205 | "SUMMERLAND CS","49.563","-119.649","BC","-3.2","0","-2.3","4.5","0","-14.3","0","",,NA,"20.4","0",NA,"","5","",,NA,"658.2","0.0","112G8L1" 206 | "MIDWAY","49.004","-118.772","BC","-5.8","2","-1.5","4.5","2","-23.5","2","55.0","2",NA,"55.0","2",NA,"34.0","12","","",NA,"689.6","0.0","1135126" 207 | "BILLINGS","49.017","-118.228","BC","-2.7","7","0.8","3.5","7","-15.5","7","54.4","7",NA,"57.0","7",NA,"29.0","10","","",NA,"496.9","0.0","1140876" 208 | "CASTLEGAR A","49.296","-117.633","BC","-2.6","0","-0.5","4.5","0","-12.0","0","67.6","0","104.0","70.0","0","78.0","33.0","8","","",NA,"639.7","0.0","1141455" 209 | "CASTLEGAR BCHPA DAM","49.343","-117.774","BC","-1.3","4","0.1","5.0","2","-9.5","2","61.0","2",NA,"73.4","2",NA,"12.0","13","","",NA,"521.2","0.0","1141457" 210 | "KASLO","49.913","-116.921","BC","-3.0","0","-0.8","5.0","0","-14.0","0","80.8","0","123.0","84.0","0","76.0","46.0","10","","",NA,"650.0","0.0","1143900" 211 | "NAKUSP CS","50.269","-117.817","BC","-2.9","0",NA,"5.6","0","-12.5","0","",,NA,"85.9","0",NA,"44.0","15","",,NA,"648.0","0.0","1145297" 212 | "NELSON NE","49.586","-117.206","BC","-2.1","0",NA,"7.0","0","-13.5","0","80.6","0",NA,"98.4","0",NA,"43.0","11","","",NA,"623.2","0.0","1145442" 213 | "NEW DENVER","49.996","-117.370","BC","-2.5","3","-0.6","5.0","3","-14.5","3","81.0","3",NA,"83.8","3",NA,"40.0","8","","",NA,"574.2","0.0","1145460" 214 | "NELSON CS","49.491","-117.305","BC","-2.1","0",NA,"4.8","0","-15.2","0","",,NA,"52.6","0",NA,"17.0","12","",,NA,"624.5","0.0","1145M29" 215 | "WARFIELD RCS","49.112","-117.739","BC","-3.7","0",NA,"4.4","0","-14.9","0","",,NA,"63.0","0",NA,"34.0","11","",,NA,"672.8","0.0","1148705" 216 | "CRESTON CAMPBELL SCIENTIFIC","49.082","-116.501","BC","-3.3","0",NA,"5.1","0","-12.7","0","",,NA,"42.4","0",NA,"22.0","10","",,NA,"659.1","0.0","114B1F0" 217 | "NELSON RIXEN CREEK","49.512","-117.399","BC","-4.6","4",NA,"5.5","4","-14.5","4","72.0","4",NA,"72.0","4",NA,"52.0","10","","",NA,"610.1","0.0","114EMDM" 218 | "CRANBROOK A","49.612","-115.782","BC","-10.0","0",NA,"5.3","0","-28.2","0","58.8","0",NA,"47.0","0",NA,"40.0","8","",,NA,"869.5","0.0","1152105" 219 | "CRANBROOK AIRPORT AUTO","49.618","-115.789","BC","-9.6","0",NA,"5.6","0","-24.7","0","",,NA,"46.0","0",NA,"37.0","8","",,NA,"855.5","0.0","1152106" 220 | "FERNIE","49.489","-115.073","BC","-7.6","9","-1.5","4.0","9","-33.0","9","51.0","9",NA,"55.0","9",NA,"52.0","9","","",NA,"562.3","0.0","1152850" 221 | "FT STEELE DANDY CRK","49.524","-115.461","BC","-8.3","9",NA,"4.5","5","-26.5","4","54.0","5",NA,"54.0","5",NA,"37.0","8","","",NA,"578.7","0.0","1153034" 222 | "KIMBERLEY PCC","49.632","-115.962","BC","-6.7","14","0.2","5.0","14","-21.0","14","58.6","14",NA,"58.6","14",NA,"","5","","",NA,"419.4","0.0","1154203" 223 | "KOOTENAY NP WEST GATE","50.631","-116.061","BC","-7.1","10","0.1","4.0","10","-21.5","10","6.0","10",NA,"6.0","10",NA,"29.0","3","","",NA,"527.7","0.0","1154410" 224 | "SPARWOOD","49.745","-114.883","BC","-10.4","0","-3.0","2.0","0","-33.0","0","56.8","0","105.0","38.0","0","71.0","30.0","8","","",NA,"879.0","0.0","1157630" 225 | "SPARWOOD CS","49.745","-114.884","BC","-10.6","0",NA,"2.5","0","-33.0","0","",,NA,"",,NA,"22.0","","",,NA,"887.2","0.0","1157631" 226 | "WASA","49.807","-115.631","BC","0.7","28","7.5","4.5","28","-9.5","27","4.2","28",NA,"4.2","28",NA,"","1","","",NA,"51.9","0.0","1158730" 227 | "ASHCROFT","50.708","-121.281","BC","-4.4","0",NA,"6.5","0","-19.3","0","",,NA,"9.8","0",NA,"","4","",,NA,"693.7","0.0","1160515" 228 | "BLUE RIVER A","52.129","-119.290","BC","-8.4","0","-1.3","1.0","0","-31.0","0","63.6","0","62.0","37.4","0","42.0","28.0","7","","",NA,"818.2","0.0","1160899" 229 | "BLUE RIVER CS","52.129","-119.290","BC","-8.9","0",NA,"1.5","0","-31.4","0","",,NA,"35.1","0",NA,"41.0","8","",,NA,"835.3","0.0","1160H99" 230 | "CLEARWATER AUTO","51.653","-120.082","BC","-6.4","0",NA,"2.2","0","-27.8","0","",,NA,"25.4","14",NA,"39.0","4","",,NA,"756.9","0.0","1161650" 231 | "CLINTON A","51.266","-121.685","BC","-11.7","9",NA,"4.1","9","-33.3","9","",,NA,"16.7","9",NA,"","5","",,NA,"653.6","0.0","1161662" 232 | "CLINTON RCS","51.144","-121.505","BC","-9.2","0",NA,"2.6","0","-26.3","0","",,NA,"45.7","0",NA,"35.0","9","",,NA,"844.5","0.0","1161663" 233 | "CRISS CREEK","51.030","-120.728","BC","-10.0","0","-2.8","2.0","0","-31.0","0","61.8","0","164.0","61.8","0","160.0","30.0","11","","",NA,"866.9","0.0","1162177" 234 | "KAMLOOPS A","50.703","-120.449","BC","-4.3","0",NA,"8.1","0","-19.5","0","32.2","0",NA,"29.4","0",NA,"19.0","8","",,NA,"690.3","0.0","1163781" 235 | "KAMLOOPS AUT","50.702","-120.442","BC","-4.0","0",NA,"7.9","0","-19.7","0","",,NA,"29.1","0",NA,"10.0","7","",,NA,"682.4","0.0","1163842" 236 | "100 MILE HOUSE 6NE","51.681","-121.217","BC","-8.5","0",NA,"4.0","0","-32.0","0","69.4","0",NA,"69.4","0",NA,"45.0","11","","",NA,"820.8","0.0","1165793" 237 | "RED LAKE","50.935","-120.800","BC","-8.0","0","-1.9","2.5","0","-23.0","0","63.0","0","138.0","63.0","0","136.0","40.0","11","","",NA,"805.2","0.0","1166658" 238 | "SILVER CREEK","50.545","-119.350","BC","-4.1","0","-1.4","6.0","0","-20.0","0","60.4","0","114.0","63.6","0","93.0","40.0","11","","",NA,"685.9","0.0","1167337" 239 | "SUN PEAKS MOUNTAIN","50.903","-119.911","BC","-7.8","0",NA,"5.0","0","-20.0","0","65.0","0",NA,"65.0","0",NA,"93.0","13","","",NA,"800.6","0.0","1168204" 240 | "VAVENBY","51.576","-119.778","BC","-6.4","0","-1.7","2.5","0","-28.0","0","65.6","0","216.0","66.0","0","160.0","38.0","12","","",NA,"757.6","0.0","1168520" 241 | "KAMLOOPS PRATT ROAD","50.630","-120.172","BC","-5.9","0",NA,"6.0","0","-21.0","0","56.8","0",NA,"56.8","0",NA,"30.0","9","","",NA,"739.5","0.0","116C8P0" 242 | "SALMON ARM CS","50.703","-119.291","BC","-3.5","0","-1.8","5.6","0","-19.3","0","",,NA,"43.8","0",NA,"24.0","9","",,NA,"665.4","0.0","116FRMN" 243 | "SUN PEAKS LOWER","50.887","-119.883","BC","-8.4","2",NA,"5.0","1","-22.0","1","76.2","1",NA,"76.2","1",NA,"56.0","15","","",NA,"765.6","0.0","116Q20D" 244 | "SUN PEAKS UPPER","50.902","-119.918","BC","-7.8","2",NA,"5.0","1","-18.0","1","75.0","1",NA,"75.0","1",NA,"117.0","13","","",NA,"748.2","0.0","116QK0M" 245 | "GOLDEN A","51.299","-116.982","BC","-8.7","0","-0.8","4.5","0","-22.0","0","42.4","0","100.0","30.8","0","70.0","28.0","9","","",NA,"827.3","0.0","1173210" 246 | "GOLDEN AIRPORT","51.300","-116.984","BC","-9.1","0",NA,"4.4","0","-21.7","0","",,NA,"33.8","0",NA,"26.0","9","",,NA,"838.7","0.0","1173220" 247 | "GOLDSTREAM RIVER","51.630","-118.425","BC","-4.0","0","2.5","4.0","0","-22.0","0","75.0","0","67.0","75.0","0","64.0","65.0","10","","",NA,"683.0","0.0","1173242" 248 | "MICA DAM","52.053","-118.585","BC","-6.6","6","-2.2","0.0","4","-17.0","5","69.4","4",NA,"69.4","4",NA,"68.0","10","","",NA,"615.8","0.0","1175122" 249 | "REVELSTOKE A","50.967","-118.183","BC","-4.5","10",NA,"3.8","10","-18.4","10","",,NA,"14.4","10",NA,"","4","",,NA,"472.6","0.0","1176745" 250 | "REVELSTOKE AIRPORT AUTO","50.958","-118.176","BC","-4.1","0",NA,"4.1","0","-18.1","0","",,NA,"44.0","0",NA,"41.0","9","",,NA,"684.3","0.0","1176755" 251 | "YOHO PARK","51.443","-116.345","BC","-14.6","0",NA,"-1.8","0","-34.4","0","",,NA,"10.8","0",NA,"80.0","4","",,NA,"1010.2","0.0","11790J1" 252 | "CHETWYND A","55.687","-121.627","BC","-7.0","0","2.2","9.0","0","-38.5","0","6.8","0","28.0","2.6","0","14.0","14.0","1","","",NA,"773.7","0.0","1181508" 253 | "DAWSON CREEK A","55.742","-120.183","BC","-6.2","3",NA,"9.1","3","-37.7","3","",,NA,"0.0","16",NA,"","0","",,NA,"676.6","0.0","1182289" 254 | "FORT ST. JOHN A","56.238","-120.740","BC","-8.1","0",NA,"6.6","0","-36.6","0","3.4","0",NA,"5.0","0",NA,"12.0","3","",,NA,"808.0","0.0","1183001" 255 | "MACKENZIE","55.299","-123.133","BC","-10.4","6",NA,"2.6","6","-35.3","6","",,NA,"1.0","6",NA,"","1","",,NA,"710.5","0.0","1184791" 256 | "MACKENZIE AIRPORT AUTO","55.305","-123.138","BC","-10.6","0",NA,"2.3","0","-34.8","0","",,NA,"8.9","0",NA,"36.0","3","",,NA,"886.1","0.0","1184793" 257 | "DEASE LAKE A","58.422","-130.031","BC","-15.1","6",NA,"7.4","6","-39.4","6","",,NA,"1.0","6",NA,"","1","",,NA,"826.4","0.0","1192341" 258 | "FORT NELSON A","58.836","-122.597","BC","-14.7","0",NA,"5.3","0","-41.3","0","12.5","0",NA,"13.9","0",NA,"39.0","4","",,NA,"1015.1","0.0","1192946" 259 | "FORT NELSON","58.841","-122.574","BC","-14.4","0",NA,"4.8","0","-41.4","0","",,NA,"9.2","0",NA,"30.0","4","",,NA,"1005.4","0.0","1192948" 260 | "DEASE LAKE (AUT)","58.426","-130.025","BC","-14.4","0",NA,"7.8","0","-40.0","0","",,NA,"6.0","0",NA,"16.0","2","",,NA,"1002.9","0.0","119BLM0" 261 | "ATLIN","59.567","-133.700","BC","-6.8","0","1.3","7.5","0","-29.5","0","2.0","0","6.0","3.2","0","9.0","0.0","3","","",NA,"767.7","0.0","1200560" 262 | "PLEASANT CAMP","59.450","-136.367","BC","-6.3","0","0.0","6.0","0","-24.0","0","22.0","0","12.0","163.5","0","75.0","0.0","16","","",NA,"753.4","0.0","1206197" 263 | -------------------------------------------------------------------------------- /data/eng-climate-summaries-British Columbia-8,2017.csv: -------------------------------------------------------------------------------- 1 | "Environment and Climate Change Canada" 2 | "Monthly Values for August - 2017" 3 | 4 | "Legend" 5 | "Stn_Name","Station Name" 6 | "Lat","Latitude (North + , degrees)" 7 | "Long","Longitude (West - , degrees)" 8 | "Prov","Province" 9 | "Tm","Mean Temperature (°C)" 10 | "DwTm","Days without Valid Mean Temperature" 11 | "D","Mean Temperature difference from Normal (1981-2010) (°C)" 12 | "Tx","Highest Monthly Maximum Temperature (°C)" 13 | "DwTx","Days without Valid Maximum Temperature" 14 | "Tn","Lowest Monthly Minimum Temperature (°C)" 15 | "DwTn","Days without Valid Minimum Temperature" 16 | "S","Snowfall (cm)" 17 | "DwS","Days without Valid Snowfall" 18 | "S%N","Percent of Normal (1981-2010) Snowfall" 19 | "P","Total Precipitation (mm)" 20 | "DwP","Days without Valid Precipitation" 21 | "P%N","Percent of Normal (1981-2010) Precipitation" 22 | "S_G","Snow on the ground at the end of the month (cm)" 23 | "Pd","Number of days with Precipitation 1.0 mm or more" 24 | "BS","Bright Sunshine (hours)" 25 | "DwBS","Days without Valid Bright Sunshine" 26 | "BS%","Percent of Normal (1981-2010) Bright Sunshine" 27 | "HDD","Degree Days below 18 °C" 28 | "CDD","Degree Days above 18 °C" 29 | "Clim_ID","Climate Identifier" 30 | "NA","Not Available" 31 | 32 | "Stn_Name","Lat","Long","Prov","Tm","DwTm","D","Tx","DwTx","Tn","DwTn","S","DwS","S%N","P","DwP","P%N","S_G","Pd","BS","DwBS","BS%","HDD","CDD","Clim_ID" 33 | "CHEMAINUS","48.935","-123.742","BC","20.9","0",NA,"31.5","0","11.5","0","0.0","0",NA,"2.7","0",NA,"0.0","1","","",NA,"2.1","91.8","1011500" 34 | "LAKE COWICHAN","48.829","-124.052","BC","20.7","13","2.7","36.0","9","8.0","9","0.0","10",NA,"5.0","10",NA,"0.0","2","","",NA,"1.5","50.8","1012055" 35 | "DISCOVERY ISLAND","48.425","-123.226","BC","",,NA,"29.0","0","",,"",,NA,"",,NA,"","","",,NA,"","","1012475" 36 | "ESQUIMALT HARBOUR","48.432","-123.439","BC","17.1","4",NA,"25.2","4","11.2","3","",,NA,"2.6","4",NA,"","2","",,NA,"28.8","4.9","1012710" 37 | "GALIANO NORTH","48.985","-123.573","BC","19.2","14",NA,"30.5","14","12.0","14","0.0","14",NA,"0.6","14",NA,"0.0","0","","",NA,"3.6","24.3","10130MN" 38 | "MALAHAT","48.575","-123.530","BC","20.9","0",NA,"32.5","0","10.3","0","",,NA,"4.2","0",NA,"","2","",,NA,"4.4","93.8","1014820" 39 | "METCHOSIN","48.374","-123.561","BC","",,NA,"",,"",,"0.0","17",NA,"0.0","17",NA,"0.0","0","","",NA,"","","1015105" 40 | "NORTH COWICHAN","48.824","-123.718","BC","",,NA,"",,"",,"0.0","0",NA,"4.4","0","15.0","0.0","1","","",NA,"","","1015628" 41 | "NORTH COWICHAN","48.824","-123.719","BC","20.0","0",NA,"33.6","0","9.1","0","",,NA,"3.4","0",NA,"","2","",,NA,"4.0","66.4","1015630" 42 | "NORTH PENDER ISLAND","48.764","-123.287","BC","20.4","3",NA,"33.0","3","10.5","3","0.0","3",NA,"3.4","3",NA,"0.0","1","","",NA,"1.9","69.8","1015638" 43 | "RACE ROCKS","48.298","-123.531","BC","15.2","0",NA,"28.2","0","10.1","0","",,NA,"",,NA,"","","",,NA,"98.4","12.6","1016640" 44 | "SAANICHTON CDA","48.622","-123.419","BC","18.5","2","1.4","28.5","1","10.0","1","0.0","1",NA,"3.6","1",NA,"0.0","1","","",NA,"12.2","27.5","1016940" 45 | "SALTSPRING ST MARY'S L","48.888","-123.546","BC","20.7","0","2.4","30.0","0","13.0","0","0.0","0",NA,"2.4","0","9.0","0.0","1","","",NA,"1.0","85.1","1016995" 46 | "SATURNA CAPMON CS","48.775","-123.128","BC","19.3","0",NA,"28.3","0","10.2","0","",,NA,"5.0","0",NA,"","1","",,NA,"19.2","58.4","1017099" 47 | "SATURNA ISLAND CS","48.784","-123.045","BC","18.4","0",NA,"26.1","0","11.9","0","",,NA,"3.8","0",NA,"","1","",,NA,"16.8","30.4","1017101" 48 | "SHAWNIGAN LAKE","48.647","-123.626","BC","20.3","0","2.5","34.5","0","10.5","0","0.0","0",NA,"4.4","0","16.0","0.0","1","","",NA,"4.4","76.9","1017230" 49 | "SHERINGHAM POINT","48.377","-123.921","BC","14.4","0",NA,"30.4","0","9.0","0","",,NA,"6.4","0",NA,"","2","",,NA,"116.5","6.0","1017254" 50 | "VICTORIA UNIVERSITY CS","48.457","-123.305","BC","18.5","0",NA,"29.7","0","9.0","0","",,NA,"1.1","0",NA,"","0","",,NA,"13.0","29.9","1018598" 51 | "VICTORIA FRANCIS PARK","48.476","-123.443","BC","",,NA,"",,"",,"0.0","0",NA,"0.0","0","0.0","0.0","0","","",NA,"","","1018605" 52 | "VICTORIA GONZALES CS","48.413","-123.325","BC","17.3","0",NA,"29.2","0","10.6","0","",,NA,"1.4","0",NA,"","1","",,NA,"42.9","21.7","1018611" 53 | "VICTORIA INTL A","48.647","-123.426","BC","18.2","0",NA,"29.6","0","9.8","0","0.0","0",NA,"3.4","0",NA,"","2","",,NA,"17.7","22.7","1018621" 54 | "WILLIAM HEAD","48.340","-123.539","BC","18.6","0","2.1","27.0","0","10.0","0","0.0","0",NA,"2.6","0","12.0","0.0","1","","",NA,"6.3","24.9","1018935" 55 | "BALLENAS ISLAND","49.350","-124.160","BC","19.4","0",NA,"25.4","0","14.2","0","",,NA,"3.2","0",NA,"","1","",,NA,"3.1","46.0","1020590" 56 | "CAMPBELL RIVER A","49.952","-125.273","BC","18.9","0","1.7","34.0","0","7.0","0","0.0","0",NA,"6.4","0","14.0","0.0","2","","",NA,"22.5","51.2","1021261" 57 | "CAPE MUDGE","49.998","-125.195","BC","19.2","0","2.0","30.5","0","11.5","0","0.0","0",NA,"6.0","0","13.0","0.0","2","","",NA,"6.1","41.9","1021330" 58 | "CHROME ISLAND","49.472","-124.683","BC","20.1","0",NA,"32.0","0","12.0","0","0.0","0",NA,"1.6","0",NA,"0.0","1","","",NA,"1.2","67.5","1021500" 59 | "COMOX A","49.717","-124.900","BC","19.8","0","1.9","30.1","0","11.5","0","0.0","0",NA,"6.4","0","22.0","","1","",,NA,"4.0","59.9","1021830" 60 | "CORTES ISLAND TIBER BAY","50.071","-124.949","BC","20.2","0",NA,"31.5","0","8.5","0","0.0","0",NA,"10.0","0",NA,"0.0","2","","",NA,"3.9","73.3","1021960" 61 | "COURTENAY GRANTHAM","49.763","-124.999","BC","20.9","15",NA,"30.5","15","10.5","15","0.0","15",NA,"7.6","15",NA,"","1","","",NA,"0.0","47.1","1021988" 62 | "COURTENAY PUNTLEDGE","49.686","-125.033","BC","19.3","17",NA,"33.5","12","7.0","11","0.0","12",NA,"1.2","12",NA,"0.0","0","","",NA,"5.0","23.1","1021989" 63 | "ENTRANCE ISLAND","49.209","-123.811","BC","19.4","0",NA,"25.9","0","14.7","0","",,NA,"2.4","0",NA,"","1","",,NA,"3.4","48.2","1022689" 64 | "FANNY ISLAND","50.454","-125.993","BC","14.6","0",NA,"27.7","0","9.8","0","",,NA,"8.8","0",NA,"","2","",,NA,"107.2","1.6","1022795" 65 | "HERIOT BAY SE","50.099","-125.203","BC","19.3","3",NA,"31.0","3","10.0","3","0.0","3",NA,"5.2","3",NA,"0.0","2","","",NA,"5.1","41.2","1023462" 66 | "LITTLE QUALICUM HATCHERY","49.353","-124.512","BC","18.4","15","2.0","32.0","15","7.5","15","0.0","15",NA,"0.0","15",NA,"0.0","0","","",NA,"8.7","15.6","1024638" 67 | "NANAIMO A","49.054","-123.870","BC","20.0","0",NA,"34.0","0","9.5","0","0.0","0",NA,"3.0","0",NA,"0.0","1","","",NA,"6.3","67.6","1025369" 68 | "NANAIMO CITY YARD","49.199","-123.988","BC","",,NA,"",,"",,"0.0","0",NA,"2.2","0","8.0","0.0","1","","",NA,"","","10253G0" 69 | "PINE ISLAND","50.976","-127.728","BC","13.9","3","0.6","19.0","3","10.0","3","0.0","3",NA,"47.4","3",NA,"0.0","13","","",NA,"113.7","0.0","1026170" 70 | "PORT HARDY A","50.681","-127.367","BC","14.8","0",NA,"27.0","0","7.1","0","0.0","0",NA,"35.0","0",NA,"","7","",,NA,"100.7","0.1","1026271" 71 | "QUALICUM BEACH AIRPORT","49.337","-124.394","BC","19.2","0",NA,"30.5","0","9.3","0","",,NA,"3.5","0",NA,"","1","",,NA,"9.9","46.0","1026562" 72 | "QUALICUM R FISH RESEARCH","49.394","-124.617","BC","19.2","4","2.4","31.0","4","10.0","4","0.0","4",NA,"4.8","4",NA,"","2","","",NA,"6.9","38.8","1026565" 73 | "QUINSAM RIVER HATCHERY","50.016","-125.304","BC","19.2","0","1.8","31.5","0","9.0","0","0.0","0",NA,"8.8","0","18.0","0.0","4","","",NA,"8.6","45.6","1026639" 74 | "SISTERS ISLAND","49.487","-124.435","BC","19.8","0",NA,"28.3","0","14.8","0","",,NA,"",,NA,"","","",,NA,"2.4","58.0","1027403" 75 | "ENTRANCE ISLAND","49.209","-123.809","BC","19.4","2",NA,"26.0","2","15.0","2","0.0","2",NA,"4.0","2",NA,"0.0","1","","",NA,"3.4","42.7","102BFHH" 76 | "CAPE BEALE LIGHT","48.786","-125.216","BC","15.1","0","1.0","27.5","0","10.0","0","0.0","0",NA,"30.6","0","41.0","0.0","2","","",NA,"98.9","8.3","1031316" 77 | "ESTEVAN POINT","49.383","-126.543","BC","16.1","4","1.4","25.0","4","10.5","4","0.0","4",NA,"41.0","4",NA,"0.0","6","","",NA,"54.0","3.9","1032730" 78 | "ESTEVAN POINT CS","49.383","-126.543","BC","15.4","0",NA,"23.7","0","10.3","0","",,NA,"45.9","0",NA,"","6","",,NA,"81.9","2.0","1032731" 79 | "LENNARD ISLAND","49.111","-125.923","BC","14.5","0",NA,"26.0","0","9.5","0","0.0","0",NA,"42.8","0","51.0","0.0","6","","",NA,"110.3","2.8","1034600" 80 | "NITINAT RIVER HATCHERY","48.859","-124.655","BC","17.7","0","1.1","34.5","0","7.0","0","0.0","0",NA,"15.6","0","17.0","0.0","2","","",NA,"32.7","24.8","1035612" 81 | "NOOTKA LIGHTSTATION","49.600","-126.617","BC","16.7","0","0.4","27.5","0","11.0","0","0.0","0",NA,"45.6","0","46.0","0.0","7","","",NA,"60.2","18.7","1035614" 82 | "PACHENA POINT","48.723","-125.097","BC","15.0","0","0.8","28.0","0","9.0","0","0.0","0",NA,"39.0","0","46.0","0.0","6","","",NA,"101.5","8.8","1035940" 83 | "PORT ALBERNI COX LAKE","49.202","-124.752","BC","19.5","7","1.9","37.0","7","8.0","7","0.0","7",NA,"4.6","7",NA,"0.0","2","","",NA,"9.1","45.7","1036208" 84 | "QUATSINO","50.534","-127.653","BC","16.2","4","0.4","29.0","4","10.0","4","0.0","4",NA,"29.2","4",NA,"0.0","7","","",NA,"53.6","3.9","1036570" 85 | "PORT ALBERNI (AUT)","49.317","-124.927","BC","20.0","3",NA,"35.9","3","6.0","3","",,NA,"0.6","3",NA,"","0","",,NA,"6.5","63.6","1036B06" 86 | "SARTINE ISLAND (AUT)","50.821","-128.908","BC","13.9","4",NA,"17.3","2","10.7","2","",,NA,"42.8","4",NA,"","9","",,NA,"109.6","0.0","1037090" 87 | "SOLANDER ISLAND (AUT)","50.112","-127.940","BC","14.2","3",NA,"19.8","3","10.3","1","",,NA,"33.6","3",NA,"","7","",,NA,"106.2","0.0","1037553" 88 | "TAHSIS VILLAGE NORTH","49.932","-126.654","BC","19.7","18",NA,"36.0","18","10.0","18","",,NA,"1.6","30",NA,"","1","","",NA,"11.9","33.6","1037899" 89 | "TOFINO A","49.082","-125.773","BC","16.0","0","1.0","31.5","0","8.5","0","0.0","0",NA,"40.6","0","46.0","0.0","6","","",NA,"75.4","12.5","1038205" 90 | "UCLUELET KENNEDY CAMP","48.945","-125.527","BC","16.3","0","1.3","32.0","0","8.5","0","0.0","0",NA,"45.4","0","52.0","0.0","2","","",NA,"65.4","13.9","1038332" 91 | "ZEBALLOS MURAUDE CREEK","50.053","-126.779","BC","18.5","0",NA,"33.0","0","3.5","0","0.0","0",NA,"43.9","0",NA,"0.0","9","","",NA,"24.1","40.4","1039035" 92 | "GIBSONS GOWER POINT","49.386","-123.541","BC","19.2","1","1.4","26.5","1","13.5","1","0.0","1",NA,"11.2","1",NA,"0.0","1","","",NA,"3.9","40.6","1043152" 93 | "MERRY ISLAND LIGHTSTATION","49.468","-123.913","BC","19.7","0","1.5","28.0","0","15.0","0","0.0","0",NA,"5.6","0","16.0","0.0","1","","",NA,"0.0","53.9","1045100" 94 | "HOWE SOUND - PAM ROCKS","49.488","-123.299","BC","19.5","0",NA,"27.3","0","14.6","0","",,NA,"17.2","0",NA,"","1","",,NA,"1.7","47.4","10459NN" 95 | "PENDER HARBOUR","49.634","-124.032","BC","",,NA,"",,"",,"0.0","0",NA,"5.0","0",NA,"0.0","1","","",NA,"","","1046115" 96 | "PORT MELLON","49.526","-123.496","BC","19.8","0",NA,"30.7","0","11.7","0","",,NA,"15.8","0",NA,"","1","",,NA,"4.0","60.6","1046332" 97 | "POWELL RIVER A","49.834","-124.500","BC","18.5","0","1.3","30.0","0","8.0","0","0.0","0",NA,"4.6","0","10.0","0.0","1","","",NA,"15.4","31.8","1046391" 98 | "POWELL RIVER","49.835","-124.497","BC","18.6","0",NA,"30.2","0","8.4","0","",,NA,"",,NA,"","","",,NA,"14.4","33.2","1046392" 99 | "SECHELT AUT","49.458","-123.715","BC","19.0","0",NA,"30.2","0","10.1","0","",,NA,"5.6","0",NA,"","2","",,NA,"11.9","41.5","1047172" 100 | "SQUAMISH AIRPORT","49.783","-123.161","BC","19.7","0",NA,"33.2","0","8.9","0","",,NA,"3.1","0",NA,"","1","",,NA,"5.1","59.3","10476F0" 101 | "WHISTLER","50.129","-122.955","BC","19.2","0","2.8","35.0","0","5.5","0","0.0","0",NA,"3.2","0","7.0","0.0","1","","",NA,"20.3","59.0","1048898" 102 | "CAPE ST JAMES","51.936","-131.016","BC","13.8","2",NA,"21.0","1","10.9","1","",,NA,"113.8","2",NA,"","23","",,NA,"122.1","0.0","1051351" 103 | "KINDAKUN ROCKS (AUT)","53.316","-132.772","BC","13.7","2",NA,"16.6","1","11.1","1","",,NA,"199.6","2",NA,"","17","",,NA,"123.4","0.0","1054222" 104 | "LANGARA","54.255","-133.058","BC","13.6","1","0.0","19.0","1","10.5","1","0.0","1",NA,"170.0","1",NA,"0.0","16","",,NA,"131.6","0.0","1054500" 105 | "LANGARA ISLAND RCS","54.255","-133.058","BC","13.4","9",NA,"17.0","9","10.9","8","",,NA,"146.9","9",NA,"","11","",,NA,"101.4","0.0","1054503" 106 | "ROSE SPIT (AUT)","54.159","-131.661","BC","14.2","0",NA,"18.7","0","8.0","0","",,NA,"178.8","0",NA,"","17","",,NA,"117.2","0.0","1056869" 107 | "SANDSPIT AIRPORT AUTO","53.249","-131.813","BC","15.7","0",NA,"23.6","0","9.6","0","",,NA,"50.1","0",NA,"","13","",,NA,"74.6","3.5","1057051" 108 | "SANDSPIT","53.254","-131.814","BC","16.1","7",NA,"22.7","7","9.5","7","",,NA,"33.8","7",NA,"","10","",,NA,"49.3","2.7","1057052" 109 | "ADDENBROKE ISLAND","51.604","-127.864","BC","15.8","1","0.6","29.0","1","10.5","1","0.0","1",NA,"181.2","1",NA,"0.0","15","","",NA,"69.8","3.8","1060080" 110 | "BELLA BELLA","52.185","-128.157","BC","15.7","5",NA,"32.9","5","6.8","5","",,NA,"168.0","5",NA,"","13","",,NA,"64.7","5.6","1060815" 111 | "BELLA COOLA A","52.388","-126.596","BC","17.6","0","0.7","35.0","0","1.0","0","0.0","0",NA,"52.1","0","86.0","0.0","11","","",NA,"41.9","30.5","1060841" 112 | "BELLA COOLA AIRPORT","52.389","-126.587","BC","17.3","0",NA,"35.1","0","8.6","0","",,NA,"41.9","0",NA,"","9","",,NA,"42.9","20.7","1060844" 113 | "BOAT BLUFF","52.643","-128.524","BC","16.0","0","0.9","33.5","0","10.5","0","0.0","0",NA,"302.4","0","131.0","0.0","18","","",NA,"81.8","18.4","1060901" 114 | "BONILLA ISLAND","53.493","-130.638","BC","14.0","1","0.0","19.5","1","11.0","1","0.0","1",NA,"193.4","1",NA,"0.0","18","","",NA,"120.8","0.0","1060902" 115 | "BONILLA ISLAND (AUT)","53.493","-130.639","BC","13.2","5",NA,"16.8","5","11.0","1","",,NA,"95.4","5",NA,"","12","",,NA,"123.6","0.0","1060R0K" 116 | "CATHEDRAL POINT (AUT)","52.187","-127.471","BC","16.6","3",NA,"32.1","2","10.5","1","",,NA,"158.2","3",NA,"","15","",,NA,"57.6","18.2","1061458" 117 | "CUMSHEWA ISLAND","53.030","-131.602","BC","15.4","2",NA,"22.0","1","11.2","1","",,NA,"12.4","2",NA,"","5","",,NA,"77.2","2.8","1062251" 118 | "DRYAD POINT","52.185","-128.112","BC","16.4","0","0.6","31.0","0","10.5","0","0.0","0",NA,"188.6","0","130.0","0.0","16","","",NA,"62.1","13.3","1062544" 119 | "GREEN ISLAND","54.569","-130.708","BC","14.4","0","-0.4","23.5","0","11.0","0","0.0","0",NA,"219.5","0","132.0","0.0","18","","",NA,"113.0","0.3","1063298" 120 | "GREY ISLET (AUT)","54.580","-130.698","BC","14.4","2",NA,"22.5","1","11.7","1","",,NA,"174.2","2",NA,"","17","",,NA,"103.4","0.2","1063303" 121 | "HERBERT ISLAND (AUT)","50.940","-127.632","BC","13.6","0",NA,"18.7","0","9.4","0","",,NA,"28.2","0",NA,"","9","",,NA,"136.5","0.0","1063461" 122 | "HOLLAND ROCK","54.172","-130.361","BC","13.7","0",NA,"21.2","0","11.2","0","",,NA,"161.4","0",NA,"","13","",,NA,"132.0","0.0","1063496" 123 | "IVORY ISLAND","52.270","-128.407","BC","15.5","0","0.7","27.0","0","11.5","0","0.0","0",NA,"200.4","0","122.0","0.0","15","","",NA,"80.0","3.8","1063690" 124 | "KEMANO","53.563","-127.943","BC","17.5","1","1.0","35.0","1","10.0","0","0.0","1",NA,"112.2","1",NA,"0.0","19","","",NA,"61.7","45.5","1064020" 125 | "KITIMAT TOWNSITE","54.054","-128.634","BC","16.9","0","0.4","35.0","0","6.0","0","0.0","0",NA,"143.6","0","150.0","0.0","16","","",NA,"80.1","46.0","1064320" 126 | "KITIMAT 2","54.010","-128.705","BC","17.4","6","0.3","35.0","6","5.0","6","0.0","6",NA,"145.9","6",NA,"0.0","14","","",NA,"60.0","44.8","1064321" 127 | "LUCY ISLAND LIGHTSTATION","54.296","-130.609","BC","13.7","0",NA,"19.6","0","11.1","0","",,NA,"",,NA,"","","",,NA,"132.8","0.0","1064728" 128 | "MCINNES ISLAND","52.262","-128.719","BC","14.8","0","0.1","19.5","0","11.5","0","0.0","0",NA,"153.0","0","115.0","0.0","14","",,NA,"100.3","0.0","1065010" 129 | "PRINCE RUPERT","54.286","-130.445","BC","14.2","8",NA,"24.4","8","9.9","7","",,NA,"246.5","8",NA,"","15","",,NA,"88.3","0.1","1066482" 130 | "PRINCE RUPERT MONT CIRC","54.320","-130.290","BC","",,NA,"",,"",,"0.0","14",NA,"212.4","14",NA,"0.0","9","","",NA,"","","1066488" 131 | "TERRACE PCC","54.502","-128.625","BC","18.0","1","1.3","34.5","1","9.0","1","0.0","1",NA,"61.0","1",NA,"0.0","13","","",NA,"49.6","50.5","1068131" 132 | "TERRACE A","54.469","-128.578","BC","17.3","2",NA,"33.7","0","8.3","2","0.0","0",NA,"79.2","0",NA,"","11","",,NA,"64.9","45.7","1068134" 133 | "TRIPLE ISLAND","54.295","-130.880","BC","14.0","0",NA,"19.5","0","11.5","0","0.0","0",NA,"144.6","0",NA,"0.0","17","","",NA,"123.2","0.0","1068250" 134 | "EQUITY SILVER","54.199","-126.277","BC","13.2","0","1.6","27.5","0","3.5","0","0.0","0",NA,"25.8","0","48.0","0.0","5","","",NA,"155.2","5.3","1072692" 135 | "HOUSTON","54.396","-126.668","BC","16.1","8",NA,"31.5","8","3.0","8","0.0","13",NA,"1.0","13",NA,"0.0","1","","",NA,"51.4","7.8","1073615" 136 | "SMITHERS","54.825","-127.183","BC","17.0","9",NA,"31.6","9","4.2","9","",,NA,"11.1","9",NA,"","2","",,NA,"41.7","19.8","1077499" 137 | "SMITHERS A","54.825","-127.183","BC","16.6","0","2.0","33.0","0","5.0","0","0.0","0",NA,"16.8","0","38.0","0.0","5","","",NA,"71.6","27.5","1077500" 138 | "SMITHERS AIRPORT AUTO","54.824","-127.189","BC","16.3","0",NA,"31.7","0","4.8","0","",,NA,"27.6","0",NA,"","5","",,NA,"76.4","24.5","1077501" 139 | "SUSKWA VALLEY","55.289","-127.171","BC","13.7","2","-0.3","30.5","2","2.5","2","0.0","2",NA,"55.2","2",NA,"0.0","13","","",NA,"130.8","4.9","107G879" 140 | "OOTSA LAKESKINS LAKE CLIMATE","53.772","-125.997","BC","15.4","0",NA,"28.8","0","6.4","0","",,NA,"9.2","0",NA,"","2","",,NA,"90.0","8.1","1085836" 141 | "PEMBERTON AIRPORT CS","50.306","-122.734","BC","20.8","0",NA,"36.8","0","7.7","0","",,NA,"1.2","0",NA,"","1","",,NA,"1.9","89.6","1086082" 142 | "PUNTZI MOUNTAIN (AUT)","52.114","-124.136","BC","15.7","0",NA,"33.8","0","-1.3","0","",,NA,"7.6","0",NA,"","1","",,NA,"78.0","7.2","1086558" 143 | "TATLAYOKO LAKE RCS","51.675","-124.403","BC","15.9","0",NA,"32.9","0","-1.2","0","",,NA,"2.3","0",NA,"","1","",,NA,"72.0","5.6","1088015" 144 | "BURNS LAKE DECKER LAKE","54.383","-125.959","BC","13.9","0",NA,"31.7","0","-0.9","0","",,NA,"10.7","0",NA,"","4","",,NA,"127.9","1.8","1091174" 145 | "FORT ST JAMES","54.455","-124.286","BC","16.0","12","1.2","30.5","12","7.0","12","0.0","12",NA,"2.0","12",NA,"0.0","1","","",NA,"44.8","6.7","1092970" 146 | "FORT ST JAMES AUTO","54.455","-124.286","BC","16.3","0",NA,"31.1","0","6.1","0","",,NA,"16.9","0",NA,"","3","",,NA,"68.4","16.1","1092975" 147 | "MCLEESE LAKE GRANITE MT","52.531","-122.286","BC","16.1","10",NA,"30.5","7","2.5","7","0.0","7",NA,"9.4","7",NA,"0.0","3","","",NA,"52.1","11.2","1095018" 148 | "PRINCE GEORGE","53.884","-122.678","BC","15.9","11",NA,"33.5","11","3.0","11","",,NA,"19.0","11",NA,"","4","",,NA,"48.9","7.2","1096439" 149 | "PRINCE GEORGE AIRPORT AUTO","53.889","-122.672","BC","15.9","3",NA,"33.7","3","3.0","1","",,NA,"18.7","3",NA,"","5","",,NA,"68.9","8.7","1096453" 150 | "PRINCE GEORGE STP","53.880","-122.768","BC","18.1","1","2.2","35.0","1","5.5","1","0.0","1",NA,"37.0","1",NA,"0.0","6","","",NA,"33.9","37.6","1096468" 151 | "QUESNEL","53.026","-122.510","BC","16.7","9",NA,"33.7","9","3.0","8","",,NA,"13.8","9",NA,"","3","",,NA,"40.9","12.1","1096629" 152 | "QUESNEL AIRPORT AUTO","53.027","-122.506","BC","17.4","0",NA,"34.9","0","3.0","0","",,NA,"16.1","0",NA,"","6","",,NA,"45.2","27.5","1096631" 153 | "SPOKIN LAKE 4E","52.184","-121.686","BC","13.8","0","1.0","33.0","0","-4.0","0","0.0","0",NA,"25.8","0","49.0","0.0","7","","",NA,"131.2","0.3","1097646" 154 | "WILLIAMS LAKE A","52.183","-122.054","BC","17.6","1",NA,"31.9","1","2.7","0","0.0","12",NA,"11.8","18",NA,"","3","",,NA,"47.1","35.2","1098941" 155 | "VANDERHOOF","54.033","-124.017","BC","17.1","0","1.3","33.5","0","5.5","0","0.0","0",NA,"17.6","0","41.0","0.0","5","","",NA,"49.5","22.8","1098D90" 156 | "108 MILE HOUSE ABEL LAKE","51.623","-121.263","BC","18.1","1",NA,"35.0","1","3.5","1","0.0","1",NA,"11.0","1",NA,"0.0","3","","",NA,"37.5","39.1","109E7R6" 157 | "ABBOTSFORD A","49.025","-122.360","BC","20.0","2",NA,"34.1","2","9.4","0","0.0","0",NA,"3.2","1",NA,"","1","",,NA,"2.7","60.1","1100031" 158 | "AGASSIZ RCS","49.243","-121.760","BC","20.1","3","1.3","33.3","3","8.5","1","",,NA,"7.7","4",NA,"","1","",,NA,"4.5","62.4","1100119" 159 | "AGASSIZ CDA","49.243","-121.760","BC","20.0","4","1.3","35.5","2","9.0","2","0.0","2",NA,"9.2","2",NA,"0.0","1","","",NA,"5.7","60.0","1100120" 160 | "WHISTLER - NESTERS","50.129","-122.955","BC","19.1","0",NA,"34.6","0","5.8","0","",,NA,"2.1","0",NA,"","1","",,NA,"26.0","59.8","1100875" 161 | "BLACKCOMB BASE SLIDING CENTER","50.102","-122.936","BC","19.2","0",NA,"32.2","0","7.1","0","",,NA,"1.7","0",NA,"","1","",,NA,"41.6","80.3","1100881" 162 | "BURNABY SIMON FRASER U","49.278","-122.918","BC","20.6","1","3.4","30.0","1","11.0","1","0.0","1",NA,"12.4","1",NA,"0.0","2","","",NA,"7.8","84.7","1101158" 163 | "CALLAGHAN VALLEY","50.144","-123.111","BC","18.4","0",NA,"32.5","0","5.5","0","",,NA,"4.5","0",NA,"","2","",,NA,"47.2","61.1","1101300" 164 | "CLOVERDALE EAST","49.109","-122.698","BC","20.7","3",NA,"32.5","3","11.5","3","0.0","3",NA,"5.4","3",NA,"0.0","1","","",NA,"0.9","75.8","1101708" 165 | "DELTA BURNS BOG","49.126","-123.002","BC","18.4","0",NA,"30.1","0","7.3","0","",,NA,"6.9","0",NA,"","1","",,NA,"14.8","26.7","1102415" 166 | "DELTA TSAWWASSEN BEACH","49.011","-123.093","BC","17.7","1","-0.2","27.5","1","9.5","1","0.0","1",NA,"5.2","1",NA,"0.0","1","","",NA,"22.8","15.1","1102425" 167 | "FORT LANGLEY TELEGRAPH TRAIL","49.145","-122.551","BC","20.3","0",NA,"33.0","0","9.5","0","0.0","0",NA,"6.0","0",NA,"0.0","2","","",NA,"3.8","74.8","1102912" 168 | "HANEY UBC RF ADMIN","49.264","-122.573","BC","20.6","0","2.8","33.0","0","10.0","0","0.0","0",NA,"8.5","0","12.0","0.0","1","","",NA,"4.2","85.2","1103332" 169 | "MISSION WEST ABBEY","49.153","-122.271","BC","21.1","0","2.8","32.5","0","11.5","0","0.0","0",NA,"8.6","0","14.0","0.0","1","","",NA,"3.4","100.1","1105192" 170 | "RICHMOND OPERATIONS CENTRE","49.182","-123.078","BC","",,NA,"",,"",,"",,NA,"6.9","0",NA,"","1","",,NA,"","","1105210" 171 | "N VANC GROUSE MTN RESORT","49.381","-123.078","BC","17.7","8","3.7","31.0","8","0.0","8","0.0","8",NA,"30.0","8",NA,"","2","","",NA,"50.8","44.6","1105658" 172 | "N VANCOUVER WHARVES","49.315","-123.115","BC","",,NA,"",,"",,"0.0","10",NA,"12.0","10",NA,"","2","","",NA,"","","1105669" 173 | "PITT MEADOWS CS","49.208","-122.690","BC","20.7","0",NA,"33.0","0","10.4","0","",,NA,"6.5","0",NA,"","1","",,NA,"0.4","84.9","1106178" 174 | "POINT ATKINSON","49.330","-123.265","BC","19.0","5",NA,"27.4","5","14.2","3","",,NA,"16.6","5",NA,"","4","",,NA,"5.4","31.2","1106200" 175 | "RICHMOND DALLYN 2","49.179","-123.087","BC","",,NA,"",,"",,"0.0","0",NA,"7.4","0",NA,"0.0","1","","",NA,"","","1106764" 176 | "PORT MOODY GLENAYRE","49.279","-122.881","BC","20.4","0","2.3","31.0","0","12.0","0","0.0","0",NA,"10.0","0","15.0","0.0","1","","",NA,"2.0","75.6","1106CL2" 177 | "RICHMOND NATURE PARK","49.171","-123.093","BC","19.9","2","1.7","31.5","2","9.5","2","0.0","2",NA,"7.6","2",NA,"0.0","1","","",NA,"0.7","56.4","1106PF7" 178 | "SANDHEADS CS","49.106","-123.303","BC","18.9","0",NA,"24.5","0","14.0","0","",,NA,"",,NA,"","","",,NA,"7.1","33.5","1107010" 179 | "SUMAS CANAL","49.113","-122.110","BC","23.9","26",NA,"38.0","21","4.5","20","0.0","21",NA,"1.0","21",NA,"0.0","1","","",NA,"0.0","29.6","1107785" 180 | "VANCOUVER SEA ISLAND CCG","49.183","-123.187","BC","19.3","0",NA,"29.7","0","11.6","0","",,NA,"7.3","0",NA,"","1","",,NA,"2.5","41.4","1108380" 181 | "VANCOUVER INTL A","49.195","-123.184","BC","18.8","0",NA,"29.5","0","10.9","0","0.0","0",NA,"5.0","0",NA,"","1","",,NA,"6.7","32.5","1108395" 182 | "VANCOUVER HARBOUR CS","49.295","-123.122","BC","19.9","1",NA,"30.5","1","13.6","0","",,NA,"10.1","1",NA,"","1","",,NA,"0.1","57.6","1108446" 183 | "WEST VANCOUVER AUT","49.347","-123.193","BC","20.7","0",NA,"31.8","0","12.6","0","",,NA,"14.6","0",NA,"","1","",,NA,"2.4","85.2","1108824" 184 | "WHISTLER ROUNDHOUSE","50.068","-122.947","BC","14.3","3",NA,"25.0","3","3.5","3","0.0","3",NA,"0.5","3",NA,"0.0","0","","",NA,"113.4","11.1","1108906" 185 | "WHITE ROCK CAMPBELL SCIENTIFIC","49.018","-122.784","BC","18.5","0",NA,"29.5","0","10.6","0","",,NA,"5.0","0",NA,"","1","",,NA,"9.4","26.1","1108910" 186 | "N VAN SEYMOUR HATCHERY","49.438","-122.967","BC","19.4","3","2.1","32.0","2","9.0","3","0.0","2",NA,"15.8","2",NA,"0.0","1","","",NA,"14.5","53.5","110N666" 187 | "HOPE A","49.368","-121.498","BC","21.7","2",NA,"37.2","1","9.4","1","",,NA,"3.6","2",NA,"","2","",,NA,"1.6","107.6","1113542" 188 | "HOPE AIRPORT","49.370","-121.493","BC","21.5","0",NA,"37.4","0","9.5","0","",,NA,"2.9","0",NA,"","1","",,NA,"2.0","111.2","1113543" 189 | "HOPE SLIDE","49.267","-121.233","BC","17.9","0","2.7","33.0","0","5.0","0","0.0","0",NA,"3.6","0","9.0","0.0","1","","",NA,"41.5","39.3","1113581" 190 | "LILLOOET","50.684","-121.934","BC","24.2","0",NA,"38.9","0","10.2","0","",,NA,"",,NA,"","","",,NA,"0.0","192.8","1114619" 191 | "LYTTON A","50.224","-121.582","BC","24.2","0",NA,"39.3","0","12.1","0","",,NA,"0.0","0",NA,"","0","",,NA,"0.0","190.7","1114738" 192 | "LYTTON RCS","50.224","-121.582","BC","24.3","0",NA,"40.1","0","12.1","0","",,NA,"0.2","0",NA,"","0","",,NA,"0.0","196.2","1114746" 193 | "HEDLEY N","49.364","-120.069","BC","24.0","12",NA,"41.0","12","9.0","12","0.0","12",NA,"0.6","12",NA,"","0","","",NA,"0.0","114.9","1123370" 194 | "JELLICOE","49.673","-120.333","BC","18.9","3",NA,"36.0","3","2.5","3","0.0","3",NA,"2.4","3",NA,"0.0","1","","",NA,"24.5","48.9","1123721" 195 | "KELOWNA","49.957","-119.378","BC","20.2","3",NA,"34.0","3","4.4","3","",,NA,"0.0","3",NA,"","0","",,NA,"7.1","69.1","1123939" 196 | "KELOWNA UBCO","49.941","-119.400","BC","22.2","0",NA,"35.8","0","7.7","0","",,NA,"0.2","0",NA,"","0","",,NA,"2.6","132.8","1123996" 197 | "MERRITT","50.113","-120.778","BC","19.5","0",NA,"37.8","0","3.3","0","",,NA,"2.2","0",NA,"","1","",,NA,"12.6","57.9","1125073" 198 | "MERRITT STP","50.114","-120.801","BC","20.7","0","2.2","38.0","0","6.0","0","0.0","0",NA,"2.0","0","10.0","0.0","1","","",NA,"5.9","91.0","1125079" 199 | "OKANAGAN CENTRE","50.056","-119.445","BC","22.7","0","2.3","33.0","0","11.0","0","0.0","0",NA,"1.0","0","3.0","0.0","1","","",NA,"1.7","147.8","1125700" 200 | "OLIVER STP","49.179","-119.545","BC","23.8","11","2.1","37.0","11","12.0","11","0.0","11",NA,"0.0","11",NA,"0.0","0","","",NA,"0.0","116.2","1125766" 201 | "OSOYOOS CS","49.028","-119.441","BC","23.1","0","0.8","36.9","0","8.4","0","",,NA,"0.6","0",NA,"","0","",,NA,"0.0","158.8","1125852" 202 | "PEACHLAND","49.783","-119.717","BC","22.6","0","1.7","33.0","0","10.0","0","0.0","0",NA,"0.6","0","2.0","0.0","0","","",NA,"2.7","144.9","1126070" 203 | "PENTICTON A","49.463","-119.602","BC","21.4","1",NA,"34.1","1","7.2","0","0.0","1",NA,"0.0","1",NA,"","0","",,NA,"2.6","105.9","1126146" 204 | "PRINCETON A","49.468","-120.513","BC","19.7","2","1.8","37.0","2","2.5","2","0.0","2",NA,"1.2","2",NA,"0.0","1","","",NA,"15.0","64.0","1126510" 205 | "VERNON AUTO","50.223","-119.194","BC","21.4","0",NA,"34.1","0","5.7","0","",,NA,"1.0","0",NA,"","0","",,NA,"5.3","110.8","1128582" 206 | "VERNON NORTH","50.344","-119.271","BC","22.7","0","2.3","35.0","0","7.0","0","0.0","0",NA,"1.0","0","3.0","0.0","0","","",NA,"3.9","149.7","1128583" 207 | "VERNON SILVER STAR LODGE","50.359","-119.056","BC","17.4","0",NA,"29.5","0","4.0","0","0.0","0",NA,"7.8","0",NA,"0.0","2","","",NA,"62.5","43.5","1128584" 208 | "PRINCETON CS","49.465","-120.510","BC","20.1","0",NA,"37.7","0","3.7","0","",,NA,"1.0","0",NA,"","0","",,NA,"12.7","78.1","112FN0M" 209 | "SUMMERLAND CS","49.563","-119.649","BC","22.6","0","1.6","34.9","0","8.8","0","",,NA,"0.0","0",NA,"","0","",,NA,"2.5","145.8","112G8L1" 210 | "MIDWAY","49.004","-118.772","BC","20.3","0","1.6","37.5","0","2.5","0","0.0","0",NA,"2.2","0","8.0","0.0","1","","",NA,"7.3","79.1","1135126" 211 | "BILLINGS","49.017","-118.228","BC","22.6","4","2.2","37.0","4","8.5","4","0.0","4",NA,"3.8","4",NA,"","1","","",NA,"0.0","123.8","1140876" 212 | "CASTLEGAR A","49.296","-117.633","BC","22.1","0","2.1","37.0","0","6.5","0","0.0","0",NA,"8.2","0","27.0","0.0","2","","",NA,"0.7","127.0","1141455" 213 | "CASTLEGAR BCHPA DAM","49.343","-117.774","BC","22.1","0","2.2","36.0","0","10.5","0","0.0","0",NA,"14.6","0","43.0","0.0","1","","",NA,"1.0","127.5","1141457" 214 | "DUNCAN LAKE DAM","50.239","-116.972","BC","18.4","0","1.4","32.5","0","5.0","0","0.0","0",NA,"25.5","0","49.0","0.0","2","","",NA,"21.5","35.4","1142574" 215 | "KASLO","49.913","-116.921","BC","20.4","0","2.1","32.0","0","9.0","0","0.0","0",NA,"17.8","0","40.0","0.0","2","","",NA,"3.9","77.4","1143900" 216 | "NAKUSP CS","50.269","-117.817","BC","20.1","0",NA,"34.2","0","5.4","0","",,NA,"10.7","0",NA,"","1","",,NA,"15.8","80.5","1145297" 217 | "NELSON NE","49.586","-117.206","BC","21.0","0",NA,"34.5","0","8.0","0","0.0","0",NA,"23.2","0",NA,"0.0","2","","",NA,"2.2","95.8","1145442" 218 | "NEW DENVER","49.996","-117.370","BC","21.2","0","2.3","35.0","0","8.0","0","0.0","0",NA,"29.4","0","54.0","0.0","2","","",NA,"8.1","107.4","1145460" 219 | "NELSON CS","49.491","-117.305","BC","22.2","0",NA,"36.2","0","8.7","0","",,NA,"19.0","0",NA,"","1","",,NA,"0.0","130.5","1145M29" 220 | "WARFIELD RCS","49.112","-117.739","BC","23.0","1",NA,"38.4","1","8.0","0","",,NA,"3.9","1",NA,"","1","",,NA,"0.0","150.0","1148705" 221 | "CRESTON CAMPBELL SCIENTIFIC","49.082","-116.501","BC","23.1","1",NA,"35.2","1","10.7","0","",,NA,"8.4","1",NA,"","1","",,NA,"0.0","153.5","114B1F0" 222 | "NELSON RIXEN CREEK","49.512","-117.399","BC","21.4","4",NA,"35.5","4","7.5","4","0.0","4",NA,"34.3","4",NA,"0.0","2","","",NA,"5.7","98.2","114EMDM" 223 | "CRANBROOK A","49.612","-115.782","BC","20.6","2",NA,"33.9","0","3.5","2","0.0","0",NA,"2.8","0",NA,"","1","",,NA,"10.9","86.3","1152105" 224 | "CRANBROOK AIRPORT AUTO","49.618","-115.789","BC","20.7","0",NA,"33.8","0","4.0","0","",,NA,"1.0","0",NA,"","1","",,NA,"12.1","96.4","1152106" 225 | "FERNIE","49.489","-115.073","BC","18.8","6","2.5","34.0","6","2.5","6","0.0","6",NA,"21.8","6",NA,"0.0","6","","",NA,"13.9","33.3","1152850" 226 | "FT STEELE DANDY CRK","49.524","-115.461","BC","18.7","15",NA,"33.0","11","4.0","10","0.0","11",NA,"19.6","11",NA,"","4","","",NA,"10.9","22.1","1153034" 227 | "KIMBERLEY PCC","49.632","-115.962","BC","20.3","12","2.7","34.0","12","4.0","12","0.0","12",NA,"0.0","12",NA,"0.0","0","","",NA,"7.7","51.6","1154203" 228 | "KOOTENAY NP WEST GATE","50.631","-116.061","BC","20.1","8","2.4","34.0","8","5.0","8","0.0","8",NA,"0.0","8",NA,"0.0","0","","",NA,"13.8","62.8","1154410" 229 | "SPARWOOD","49.745","-114.883","BC","17.4","0","1.9","32.5","0","1.5","0","0.0","0","0.0","7.6","0","22.0","0.0","2","","",NA,"35.7","16.5","1157630" 230 | "SPARWOOD CS","49.745","-114.884","BC","17.3","0",NA,"32.5","0","1.5","0","",,NA,"7.0","0",NA,"","2","",,NA,"37.4","16.1","1157631" 231 | "WASA","49.807","-115.631","BC","20.3","6","2.6","32.5","3","5.5","3","0.0","3",NA,"26.0","3",NA,"0.0","2","","",NA,"10.1","68.4","1158730" 232 | "ASHCROFT","50.708","-121.281","BC","23.8","0",NA,"39.5","0","9.1","0","",,NA,"3.8","0",NA,"","2","",,NA,"0.3","180.1","1160515" 233 | "BLUE RIVER A","52.129","-119.290","BC","17.3","0","1.4","35.5","0","2.0","0","0.0","0",NA,"26.2","0","32.0","0.0","4","","",NA,"50.5","29.7","1160899" 234 | "BLUE RIVER CS","52.129","-119.290","BC","17.4","2",NA,"35.1","2","1.7","0","",,NA,"19.4","2",NA,"","4","",,NA,"45.4","28.5","1160H99" 235 | "CLEARWATER AUTO","51.653","-120.082","BC","19.8","0",NA,"35.7","0","4.9","0","",,NA,"21.1","0",NA,"","3","",,NA,"21.5","78.3","1161650" 236 | "CLINTON A","51.266","-121.685","BC","14.8","12",NA,"30.9","12","-1.5","11","",,NA,"10.5","12",NA,"","2","",,NA,"63.1","2.7","1161662" 237 | "CLINTON RCS","51.144","-121.505","BC","18.2","0",NA,"34.2","0","1.3","0","",,NA,"9.0","0",NA,"","2","",,NA,"38.0","44.1","1161663" 238 | "CRISS CREEK","51.030","-120.728","BC","14.9","5","1.7","32.0","5","-1.5","5","0.0","5",NA,"6.2","5",NA,"0.0","1","","",NA,"82.7","2.1","1162177" 239 | "DARFIELD","51.292","-120.183","BC","21.7","27","3.3","35.0","26","10.5","27","0.0","26",NA,"0.0","26",NA,"0.0","0","","",NA,"0.0","14.6","1162265" 240 | "KAMLOOPS A","50.703","-120.449","BC","22.1","0",NA,"38.5","0","6.9","0","0.0","0",NA,"1.8","0",NA,"","1","",,NA,"2.0","129.3","1163781" 241 | "KAMLOOPS AUT","50.702","-120.442","BC","22.0","1",NA,"38.1","1","7.0","0","",,NA,"0.8","1",NA,"","0","",,NA,"2.0","121.9","1163842" 242 | "100 MILE HOUSE 6NE","51.681","-121.217","BC","18.3","0",NA,"34.0","0","6.0","0","0.0","0",NA,"18.8","0",NA,"0.0","4","","",NA,"33.4","42.8","1165793" 243 | "RED LAKE","50.935","-120.800","BC","18.4","6","3.5","33.0","6","3.0","6","0.0","2",NA,"5.0","2",NA,"0.0","2","","",NA,"21.6","31.2","1166658" 244 | "SILVER CREEK","50.545","-119.350","BC","19.4","0","1.0","34.5","0","4.0","0","0.0","0",NA,"1.9","0","6.0","0.0","1","","",NA,"16.1","59.8","1167337" 245 | "VAVENBY","51.576","-119.778","BC","18.6","0","1.1","36.5","0","4.5","0","0.0","0",NA,"14.2","0","33.0","0.0","2","","",NA,"31.5","51.6","1168520" 246 | "KAMLOOPS PRATT ROAD","50.630","-120.172","BC","20.5","12",NA,"34.0","12","6.0","12","0.0","12",NA,"5.8","12",NA,"","1","","",NA,"12.2","59.1","116C8P0" 247 | "SALMON ARM CS","50.703","-119.291","BC","20.0","0","0.2","34.6","0","5.6","0","",,NA,"2.4","0",NA,"","1","",,NA,"11.5","73.6","116FRMN" 248 | "GOLDEN A","51.299","-116.982","BC","18.5","1","1.8","33.5","1","3.5","1","0.0","1",NA,"5.2","1",NA,"0.0","1","","",NA,"26.7","41.1","1173210" 249 | "GOLDEN AIRPORT","51.300","-116.984","BC","18.3","0",NA,"33.8","0","3.3","0","",,NA,"2.6","0",NA,"","1","",,NA,"30.3","40.6","1173220" 250 | "GOLDSTREAM RIVER","51.630","-118.425","BC","18.7","0","2.3","34.0","0","4.0","0","0.0","0",NA,"16.0","0","21.0","0.0","5","","",NA,"24.0","45.5","1173242" 251 | "MICA DAM","52.053","-118.585","BC","17.4","0","1.3","34.0","0","4.5","0","0.0","0",NA,"17.2","0","22.0","0.0","5","","",NA,"49.4","32.1","1175122" 252 | "REVELSTOKE A","50.967","-118.183","BC","18.6","4",NA,"29.0","4","7.4","4","",,NA,"4.4","4",NA,"","2","",,NA,"16.6","32.9","1176745" 253 | "REVELSTOKE AIRPORT AUTO","50.958","-118.176","BC","20.1","1",NA,"34.6","1","6.3","0","",,NA,"4.8","1",NA,"","2","",,NA,"14.6","76.2","1176755" 254 | "YOHO PARK","51.443","-116.345","BC","14.5","0",NA,"28.8","0","0.4","0","",,NA,"11.6","0",NA,"","4","",,NA,"109.5","0.3","11790J1" 255 | "YOHO NP OHARA LAKE","51.356","-116.337","BC","12.3","0",NA,"26.5","0","-1.0","0","0.0","0",NA,"26.6","0",NA,"0.0","5","","",NA,"175.4","0.0","117R00H" 256 | "CHETWYND A","55.687","-121.627","BC","15.7","0","1.3","30.5","0","3.0","0","0.0","0",NA,"15.8","0","31.0","0.0","5","","",NA,"80.5","10.4","1181508" 257 | "DAWSON CREEK A","55.742","-120.183","BC","16.4","0",NA,"31.2","0","5.0","0","",,NA,"0.0","3",NA,"","0","",,NA,"57.8","7.8","1182289" 258 | "FORT ST. JOHN A","56.238","-120.740","BC","16.2","3",NA,"30.3","0","5.9","3","0.0","1",NA,"12.0","0",NA,"","1","",,NA,"58.5","8.0","1183001" 259 | "MACKENZIE","55.299","-123.133","BC","16.4","8",NA,"32.0","8","4.4","7","",,NA,"14.5","8",NA,"","3","",,NA,"50.0","13.3","1184791" 260 | "MACKENZIE AIRPORT AUTO","55.305","-123.138","BC","16.1","0",NA,"32.5","0","3.2","0","",,NA,"21.2","0",NA,"","5","",,NA,"76.3","17.5","1184793" 261 | "DEASE LAKE A","58.422","-130.031","BC","12.4","11",NA,"30.2","11","1.3","9","",,NA,"39.2","11",NA,"","7","",,NA,"113.5","1.7","1192341" 262 | "FORT NELSON A","58.836","-122.597","BC","16.9","0",NA,"33.3","0","2.1","0","0.0","0",NA,"12.6","0",NA,"","4","",,NA,"61.2","25.7","1192946" 263 | "FORT NELSON","58.841","-122.574","BC","17.3","0",NA,"33.1","0","2.7","0","",,NA,"15.6","0",NA,"","3","",,NA,"52.3","29.8","1192948" 264 | "FORT NELSON UA","58.841","-122.573","BC","17.1","1",NA,"33.5","1","2.5","1","0.0","1",NA,"22.6","1",NA,"0.0","7","","",NA,"54.1","28.0","1192950" 265 | "TETSA RIVER","58.653","-124.236","BC","12.7","28","0.6","28.0","28","1.0","28","0.0","28",NA,"15.0","28",NA,"0.0","1","","",NA,"16.0","0.0","1195J29" 266 | "DEASE LAKE (AUT)","58.426","-130.025","BC","13.0","1",NA,"30.4","1","-1.5","0","",,NA,"40.6","1",NA,"","8","",,NA,"150.8","1.6","119BLM0" 267 | "ATLIN","59.567","-133.700","BC","13.8","0","1.3","28.0","0","3.0","0","0.0","0",NA,"19.0","0","56.0","0.0","6","","",NA,"133.7","2.0","1200560" 268 | "PLEASANT CAMP","59.450","-136.367","BC","13.0","0","-0.4","31.0","0","2.0","0","0.0","0",NA,"99.1","0","137.0","0.0","14","","",NA,"160.7","4.8","1206197" 269 | --------------------------------------------------------------------------------