EIS metadata validation script

Used to validate Planon output with spreadsheet input

1. Data import


In [436]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

Read data. There are two datasets: Planon and Master. The latter is the EIS data nomencalture that was created. Master is made up of two subsets: loggers and meters. Loggers are sometimes called controllers and meters are sometimes called sensors. In rare cases meters or sensors are also called channels.


In [493]:
planon=pd.read_excel('EIS Assets v2.xlsx',index_col = 'Code')
#master_loggerscontrollers_old = pd.read_csv('LoggersControllers.csv', index_col = 'Asset Code')
#master_meterssensors_old = pd.read_csv('MetersSensors.csv', encoding = 'macroman', index_col = 'Asset Code')
master='MASTER PlanonLoggersAndMeters 17 10 16.xlsx'
master_loggerscontrollers=pd.read_excel(master,sheetname='Loggers Controllers', index_col = 'Asset Code')
master_meterssensors=pd.read_excel(master,sheetname='Meters Sensors', encoding = 'macroman', index_col = 'Asset Code')
planon['Code']=planon.index
master_loggerscontrollers['Code']=master_loggerscontrollers.index
master_meterssensors['Code']=master_meterssensors.index

In [494]:
set(master_meterssensors['Classification Group'])


Out[494]:
{'Energy meter', 'Energy sensor'}

In [495]:
set(master_loggerscontrollers['Classification Group'])


Out[495]:
{nan, 'BMS controller', 'Data logger'}

In [496]:
new_index=[]
for i in master_meterssensors.index:
    if '/' not in i:
        new_index.append(i[:i.find('-')+1]+i[i.find('-')+1:].replace('-','/'))
    else:
        new_index.append(i)

In [497]:
master_meterssensors.index=new_index
master_meterssensors['Code']=master_meterssensors.index

In [498]:
new_index=[]
for i in master_meterssensors.index:
    logger=i[:i.find('/')]
    if master_loggerscontrollers.loc[logger]['Classification Group']=='BMS controller':
        meter=i[i.find('/')+1:]
        if meter[0] not in {'N','n','o','i'}:
            new_index.append(i)   
    else:
        new_index.append(i)

In [499]:
len(master_meterssensors)


Out[499]:
30597

In [500]:
master_meterssensors=master_meterssensors.loc[new_index]

In [501]:
len(master_meterssensors)


Out[501]:
29218

In [503]:
master_meterssensors.to_csv('meterssensors.csv')

In [504]:
master_loggerscontrollers.to_csv('loggerscontrollers.csv')

Unify index, caps everything and strip of trailing spaces.


In [505]:
planon.index=[str(i).strip() for i in planon.index]
master_loggerscontrollers.index=[str(i).strip() for i in master_loggerscontrollers.index]
master_meterssensors.index=[str(i).strip() for i in master_meterssensors.index]

Drop duplicates (shouldn't be any)


In [506]:
planon.drop_duplicates(inplace=True)
master_loggerscontrollers.drop_duplicates(inplace=True)
master_meterssensors.drop_duplicates(inplace=True)

Split Planon import into loggers and meters
Drop duplicates (shouldn't be any)


In [507]:
# Split the Planon file into 2, one for loggers & controllers, and one for meters & sensors.
planon_loggerscontrollers = planon.loc[(planon['Classification Group'] == 'EN.EN4 BMS Controller') | (planon['Classification Group'] == 'EN.EN1 Data Logger')]
planon_meterssensors = planon.loc[(planon['Classification Group'] == 'EN.EN2 Energy Meter') | (planon['Classification Group'] == 'EN.EN3 Energy Sensor')]
planon_loggerscontrollers.drop_duplicates(inplace=True)
planon_meterssensors.drop_duplicates(inplace=True)


C:\Anaconda2\envs\python3\lib\site-packages\pandas\util\decorators.py:91: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  return func(*args, **kwargs)

Index unique? show number of duplicates in index


In [508]:
len(planon_loggerscontrollers.index[planon_loggerscontrollers.index.duplicated()])


Out[508]:
0

In [509]:
len(planon_meterssensors.index[planon_meterssensors.index.duplicated()])


Out[509]:
3256

Meters are not unique. This is becasue of the spaces served. This is ok for now, we will deal with duplicates at the comparison stage. Same is true for loggers - in the unlikely event that there are duplicates in the future.


In [510]:
planon_meterssensors.head(3)


Out[510]:
BuildingNo. Building Locations.Space.Space number Space Name Additional Location Info Description Classification Group Record HVAC Ref Element Description ... Logger SIM Meter Pulse Value Meter Units Meter Capacity Network Point ID Tenant Meter.Name Fiscal Meter.Name EIS Space.Space number Utility Type.Name Code
AP000-L01/M001 AP000 Alexandra Park NaN NaN NaN NaN EN.EN2 Energy Meter NaN NaN NaN ... NaN NaN kWh NaN NaN No No NaN NaN AP000-L01/M001
AP000-L02/M001 AP000 Alexandra Park NaN NaN NaN Graduate House 1-11 EN.EN2 Energy Meter NaN NaN NaN ... NaN NaN NaN NaN NaN No No NaN NaN AP000-L02/M001
AP000-L02/M002 AP000 Alexandra Park NaN NaN NaN Alex Park Main EN.EN2 Energy Meter NaN NaN NaN ... NaN NaN NaN NaN NaN No No NaN NaN AP000-L02/M002

3 rows × 30 columns

2. Validation

Create list of all buildings present in Planon export. These are buildings to check the data against from Master.


In [511]:
buildings=set(planon_meterssensors['BuildingNo.'])
buildings


Out[511]:
{'AP000',
 'AP001',
 'AP009',
 'AP010',
 'AP011',
 'AP057',
 'AP080',
 'AP081',
 'EX001',
 'MC000',
 'MC001',
 'MC003',
 'MC007',
 'MC008',
 'MC010',
 'MC011',
 'MC013',
 'MC014',
 'MC029',
 'MC030',
 'MC031',
 'MC032',
 'MC033',
 'MC043',
 'MC044',
 'MC045',
 'MC046',
 'MC047',
 'MC048',
 'MC050',
 'MC051',
 'MC053',
 'MC055',
 'MC061',
 'MC062',
 'MC063',
 'MC064',
 'MC065',
 'MC066',
 'MC067',
 'MC068',
 'MC069',
 'MC070',
 'MC071',
 'MC072',
 'MC075',
 'MC076',
 'MC077',
 'MC078',
 'MC083',
 'MC095',
 'MC099',
 'MC102',
 'MC103',
 'MC125',
 'MC126',
 'MC128',
 'MC129',
 'MC131',
 'MC134',
 'MC138',
 'MC139',
 'MC140',
 'MC141',
 'MC171',
 'MC181',
 'MC197',
 'MC198',
 'MC199',
 'MC200',
 'MC202',
 'MC203',
 'MC204',
 'MC207',
 'MC208',
 'MC210',
 'MC211',
 'OC004',
 'OC005',
 'OC006'}

In [512]:
len(buildings)


Out[512]:
80

2.1. Meters

Create dataframe slice for validation from master_meterssensors where the only the buildings located in buildings are contained. Save this new slice into master_meterssensors_for_validation. This is done by creating sub-slices of the dataframe for each building, then concatenating them all together.


In [513]:
master_meterssensors_for_validation = \
    pd.concat([master_meterssensors.loc[master_meterssensors['Building Code'] == building] \
           for building in buildings])
master_meterssensors_for_validation.head(2)


Out[513]:
Logger Asset Code Description Make Model Meter Units Meter Pulse Value Classification Group Logger Channel Utility Type ?? ... Building Name Space Additional Location Info Tenant meter Fiscal meter Parent meter Child meters Communications type Electrical panel ID Code
MC095-L01/M001 MC095-L01 Pendle Laundrette Elster A1100 kWh 0.001 Energy meter 1 Electricity NaN ... Pendle College, Kelbrook (12) NaN L2 1.0 0.0 NaN NaN NaN NaN MC095-L01/M001
MC095-L01/M002 MC095-L01 Pendle College Laundrette Sensus HRI-A3 m3 0.001 Energy meter 2 Water NaN ... Pendle College, Kelbrook (12) NaN BT1 1.0 0.0 NaN NaN NaN NaN MC095-L01/M002

2 rows × 22 columns


In [514]:
#alternative method
master_meterssensors_for_validation2 = \
    master_meterssensors[master_meterssensors['Building Code'].isin(buildings)]
master_meterssensors_for_validation2.head(2)


Out[514]:
Logger Asset Code Description Make Model Meter Units Meter Pulse Value Classification Group Logger Channel Utility Type ?? ... Building Name Space Additional Location Info Tenant meter Fiscal meter Parent meter Child meters Communications type Electrical panel ID Code
MC046-L19/M001 MC046-L19 Meter 1 NaN NaN NaN NaN Energy meter DI1 NaN NaN ... Bowland Main NaN NaN 0.0 0.0 NaN NaN NaN NaN MC046-L19/M001
MC046-L19/M002 MC046-L19 Meter 2 NaN NaN NaN NaN Energy meter DI2 NaN NaN ... Bowland Main NaN NaN 0.0 0.0 NaN NaN NaN NaN MC046-L19/M002

2 rows × 22 columns

Planon sensors are not unique because of the spaces served convention in the two data architectures. The Planon architecture devotes a new line for each space served - hence the not unique index. The Master architecture lists all the spaces only once, as a list, therefore it has a unique index. We will need to take this into account and create matching dataframe out of planon for comparison, with a unique index.


In [515]:
len(master_meterssensors_for_validation)


Out[515]:
29188

In [516]:
len(planon_meterssensors)-len(planon_meterssensors.index[planon_meterssensors.index.duplicated()])


Out[516]:
28824

Sort datasets after index for easier comparison.


In [517]:
master_meterssensors_for_validation.sort_index(inplace=True)
planon_meterssensors.sort_index(inplace=True)


C:\Anaconda2\envs\python3\lib\site-packages\ipykernel\__main__.py:2: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  from ipykernel import kernelapp as app

2.1.1 Slicing of meters to only certain columns of comparison


In [518]:
planon_meterssensors.T


Out[518]:
AP000-L01/M001 AP000-L02/M001 AP000-L02/M002 AP000-L03/M001 AP000-L03/M002 AP001-L01/M001 AP001-L01/M002 AP001-L01/M003 AP001-L01/M004 AP001-L01/M005 ... OC006-B01/W4 OC006-B01/W5 OC006-B01/Y1 OC006-B01/Y2 OC006-B01/Y3 OC006-B01/Y4 OC006-B01/Y5 OC006-B01/Y6 OC006-B01/Z1 OC006-B01/Z2
BuildingNo. AP000 AP000 AP000 AP000 AP000 AP001 AP001 AP001 AP001 AP001 ... OC006 OC006 OC006 OC006 OC006 OC006 OC006 OC006 OC006 OC006
Building Alexandra Park Alexandra Park Alexandra Park Alexandra Park Alexandra Park House 01 - Bassenthwaite, Graduate College House 01 - Bassenthwaite, Graduate College House 01 - Bassenthwaite, Graduate College House 01 - Bassenthwaite, Graduate College House 01 - Bassenthwaite, Graduate College ... Chancellor's Wharf, Kent House Chancellor's Wharf, Kent House Chancellor's Wharf, Kent House Chancellor's Wharf, Kent House Chancellor's Wharf, Kent House Chancellor's Wharf, Kent House Chancellor's Wharf, Kent House Chancellor's Wharf, Kent House Chancellor's Wharf, Kent House Chancellor's Wharf, Kent House
Locations.Space.Space number NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Space Name NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Additional Location Info NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Description NaN Graduate House 1-11 Alex Park Main NaN NaN NaN Bar Cellar Bar Ground Services Room Bar Water ... ShuntPumpRotate Manual Shunt pump changeover Outside air temperature Immersion Sensor Thermistor TBTC Room temperature Thermistor TBTI 4DIX V Heating Boilers DHWS Immersion
Classification Group EN.EN2 Energy Meter EN.EN2 Energy Meter EN.EN2 Energy Meter EN.EN2 Energy Meter EN.EN2 Energy Meter EN.EN2 Energy Meter EN.EN2 Energy Meter EN.EN2 Energy Meter EN.EN2 Energy Meter EN.EN2 Energy Meter ... EN.EN3 Energy Sensor EN.EN3 Energy Sensor EN.EN3 Energy Sensor EN.EN3 Energy Sensor EN.EN3 Energy Sensor EN.EN3 Energy Sensor EN.EN3 Energy Sensor EN.EN3 Energy Sensor EN.EN3 Energy Sensor EN.EN3 Energy Sensor
Record NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
HVAC Ref NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Element Description NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Servicable Area NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Model NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Make NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
EIS ID 1 1 2 1 2 1 2 3 4 5 ... W4 W5 Y1 Y2 Y3 Y4 Y5 Y6 Z1 Z2
Logger Channel 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
Logger Upstream Comms Target NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Logger Modem Serial Number NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Logger IP Address NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Logger Serial Number NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Logger MAC Address NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Logger SIM NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Meter Pulse Value NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Meter Units kWh NaN NaN NaN NaN m3 kWh kWh kWh m3 ... NaN NaN Degrees Celsius NaN NaN Degrees Celsius Degrees Celsius NaN NaN NaN
Meter Capacity NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Network Point ID NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Tenant Meter.Name No No No No No No No No No No ... No No No No No No No No No No
Fiscal Meter.Name No No No No No No No No No No ... No No No No No No No No No No
EIS Space.Space number NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Utility Type.Name NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Code AP000-L01/M001 AP000-L02/M001 AP000-L02/M002 AP000-L03/M001 AP000-L03/M002 AP001-L01/M001 AP001-L01/M002 AP001-L01/M003 AP001-L01/M004 AP001-L01/M005 ... OC006-B01/W4 OC006-B01/W5 OC006-B01/Y1 OC006-B01/Y2 OC006-B01/Y3 OC006-B01/Y4 OC006-B01/Y5 OC006-B01/Y6 OC006-B01/Z1 OC006-B01/Z2

30 rows × 32080 columns


In [519]:
master_meterssensors_for_validation.T


Out[519]:
AP000-L01/M001 AP000-L02/M001 AP000-L02/M002 AP000-L03/M001 AP000-L03/M002 AP000-L99/M303 AP000-L99/M308 AP001-L01/M001 AP001-L01/M002 AP001-L01/M003 ... OC006-B01/Y1 OC006-B01/Y2 OC006-B01/Y3 OC006-B01/Y4 OC006-B01/Y5 OC006-B01/Y6 OC006-B01/Z1 OC006-B01/Z2 OC006-L99/M200 OC006-L99/M503
Logger Asset Code AP000-L01 AP000-L02 AP000-L02 AP000-L03 AP000-L03 AP000-L99 AP000-L99 AP001-L01 AP001-L01 AP001-L01 ... OC006-B01 OC006-B01 OC006-B01 OC006-B01 OC006-B01 OC006-B01 OC006-B01 OC006-B01 OC006-L99 OC006-L99
Description NaN Graduate House 1-11 Alex Park Main NaN NaN Alex Park LU Alex Park UPP NaN Bar Cellar Bar Ground ... Outside air temperature Immersion Sensor Thermistor TBTC Room temperature Thermistor TBTI 4DIX V Heating Boilers DHWS Immersion Kent House Kent House
Make Carlo Gavazzi Actaris Delta NaN NaN Elster Landis ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Model EM24 Delta G D35 NaN NaN A1100 E1100 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Meter Units kWh NaN NaN NaN NaN NaN NaN m3 kWh kWh ... Degrees Celsius NaN NaN Degrees Celsius Degrees Celsius NaN NaN NaN kWh NaN
Meter Pulse Value 1 NaN NaN NaN NaN NaN NaN 0.001 0.001 0.001 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Classification Group Energy meter Energy meter Energy meter Energy meter Energy meter Energy meter Energy meter Energy meter Energy meter Energy meter ... Energy sensor Energy sensor Energy sensor Energy sensor Energy sensor Energy sensor Energy sensor Energy sensor Energy meter Energy meter
Logger Channel 1 1 2 1 2 NaN NaN 1 2 3 ... Y1 Y2 Y3 Y4 Y5 Y6 Z1 Z2 NaN NaN
Utility Type Electricity Natural Gas Natural Gas Water Water Natural Gas Natural Gas Water Electricity Electricity ... NaN NaN NaN NaN NaN NaN NaN NaN Electricity Water
?? NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Meter Type NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Building Code AP000 AP000 AP000 AP000 AP000 AP000 AP000 AP001 AP001 AP001 ... OC006 OC006 OC006 OC006 OC006 OC006 OC006 OC006 OC006 OC006
Building Name Alexandra Park Alexandra Park Alexandra Park Alexandra Park Alexandra Park Alexandra Park Alexandra Park House 01 - Bassenthwaite House 01 - Bassenthwaite House 01 - Bassenthwaite ... Chancellor's Wharf, Kent House Chancellor's Wharf, Kent House Chancellor's Wharf, Kent House Chancellor's Wharf, Kent House Chancellor's Wharf, Kent House Chancellor's Wharf, Kent House Chancellor's Wharf, Kent House Chancellor's Wharf, Kent House Chancellor's Wharf, Kent House Chancellor's Wharf, Kent House
Space NaN NaN NaN NaN NaN AP001 A0, AP002 A0, AP003 A0, AP004 A0, Ap005 ... AP012 A0, AP013 A0, AP014 A0, AP015 A0, AP016 ... NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN OC006 A0 OC006 A0
Additional Location Info Graduate 1-11 Plant Room External Gas Meter Building External Gas Meter Building External Water Meter Chamber External Water Meter Chamber NaN NaN Bassenthwaite Rm No 104 Bassenthwaite Rm No 104 Bassenthwaite Rm No 104 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Tenant meter 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
Fiscal meter 0 0 0 0 0 1 1 0 0 0 ... 0 0 0 0 0 0 0 0 1 1
Parent meter NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Child meters NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Communications type NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Electrical panel ID NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Code AP000-L01/M001 AP000-L02/M001 AP000-L02/M002 AP000-L03/M001 AP000-L03/M002 AP000-L99/M303 AP000-L99/M308 AP001-L01/M001 AP001-L01/M002 AP001-L01/M003 ... OC006-B01/Y1 OC006-B01/Y2 OC006-B01/Y3 OC006-B01/Y4 OC006-B01/Y5 OC006-B01/Y6 OC006-B01/Z1 OC006-B01/Z2 OC006-L99/M200 OC006-L99/M503

22 rows × 29188 columns

Create dictionary that maps Planon column names onto Master.

From Nicola:

  • Code (Asset Code)
  • Description
  • EIS ID (Channel)
  • Utility Type
  • Fiscal Meter
  • Tenant Meter

Building code and Building name are implicitly included. Logger Serial Number, IP or MAC would be essential to include, as well as Make and Model. Additional Location Info is not essnetial but would be useful to have. Locations (Locations.Space.Space number and Space Name) are included in the Planon export - but this is their only viable data source, therefore are not validated against.


In [520]:
#Planon:Master
meters_match_dict={
      "BuildingNo.":"Building Code",
      "Building":"Building Name",
      "Description":"Description",
      "EIS ID":"Logger Channel",
      "Tenant Meter.Name":"Tenant meter",
      "Fiscal Meter.Name":"Fiscal meter",
      "Code":"Code"
      }

Filter both dataframes based on these new columns. Then remove duplicates. Currently, this leads to loss of information of spaces served, but also a unique index for the Planon dataframe, therefore bringing the dataframes closer to each other. When including spaces explicitly in the comparison (if we want to - or just trust the Planon space mapping), this needs to be modified.


In [521]:
master_meterssensors_for_validation_filtered=master_meterssensors_for_validation[list(meters_match_dict.values())]
planon_meterssensors_filtered=planon_meterssensors[list(meters_match_dict.keys())]

In [522]:
master_meterssensors_for_validation_filtered.head(2)


Out[522]:
Fiscal meter Logger Channel Code Tenant meter Description Building Name Building Code
AP000-L01/M001 0.0 1 AP000-L01/M001 0.0 NaN Alexandra Park AP000
AP000-L02/M001 0.0 1 AP000-L02/M001 0.0 Graduate House 1-11 Alexandra Park AP000

In [523]:
planon_meterssensors_filtered.head(2)


Out[523]:
Fiscal Meter.Name EIS ID Code Tenant Meter.Name Description Building BuildingNo.
AP000-L01/M001 No 1 AP000-L01/M001 No NaN Alexandra Park AP000
AP000-L02/M001 No 1 AP000-L02/M001 No Graduate House 1-11 Alexandra Park AP000

Unify headers, drop duplicates (bear the mind the spaces argument, this where it needs to be brought back in in the future!).


In [524]:
planon_meterssensors_filtered.columns=[meters_match_dict[i] for i in planon_meterssensors_filtered]

In [525]:
planon_meterssensors_filtered.drop_duplicates(inplace=True)
master_meterssensors_for_validation_filtered.drop_duplicates(inplace=True)


C:\Anaconda2\envs\python3\lib\site-packages\pandas\util\decorators.py:91: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  return func(*args, **kwargs)

In [526]:
planon_meterssensors_filtered.head(2)


Out[526]:
Fiscal meter Logger Channel Code Tenant meter Description Building Name Building Code
AP000-L01/M001 No 1 AP000-L01/M001 No NaN Alexandra Park AP000
AP000-L02/M001 No 1 AP000-L02/M001 No Graduate House 1-11 Alexandra Park AP000

Fiscal/Tenant meter name needs fixing from Yes/No and 1/0.


In [527]:
planon_meterssensors_filtered['Fiscal meter']=planon_meterssensors_filtered['Fiscal meter'].isin(['Yes'])
planon_meterssensors_filtered['Tenant meter']=planon_meterssensors_filtered['Tenant meter'].isin(['Yes'])
master_meterssensors_for_validation_filtered['Fiscal meter']=master_meterssensors_for_validation_filtered['Fiscal meter'].isin([1])
master_meterssensors_for_validation_filtered['Tenant meter']=master_meterssensors_for_validation_filtered['Tenant meter'].isin([1])


C:\Anaconda2\envs\python3\lib\site-packages\ipykernel\__main__.py:1: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  if __name__ == '__main__':
C:\Anaconda2\envs\python3\lib\site-packages\ipykernel\__main__.py:2: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  from ipykernel import kernelapp as app
C:\Anaconda2\envs\python3\lib\site-packages\ipykernel\__main__.py:3: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  app.launch_new_instance()
C:\Anaconda2\envs\python3\lib\site-packages\ipykernel\__main__.py:4: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

In [528]:
master_meterssensors_for_validation_filtered.head(2)


Out[528]:
Fiscal meter Logger Channel Code Tenant meter Description Building Name Building Code
AP000-L01/M001 False 1 AP000-L01/M001 False NaN Alexandra Park AP000
AP000-L02/M001 False 1 AP000-L02/M001 False Graduate House 1-11 Alexandra Park AP000

In [529]:
planon_meterssensors_filtered.head(2)


Out[529]:
Fiscal meter Logger Channel Code Tenant meter Description Building Name Building Code
AP000-L01/M001 False 1 AP000-L01/M001 False NaN Alexandra Park AP000
AP000-L02/M001 False 1 AP000-L02/M001 False Graduate House 1-11 Alexandra Park AP000

Cross-check missing meters


In [530]:
a=np.sort(list(set(planon_meterssensors_filtered.index)))
b=np.sort(list(set(master_meterssensors_for_validation_filtered.index)))
meterssensors_not_in_planon=[]
for i in b:
    if i not in a:
        print(i+',',end=" "),
        meterssensors_not_in_planon.append(i)
print('\n\nMeters in Master, but not in Planon:',
      len(meterssensors_not_in_planon),'/',len(b),':',
      round(len(meterssensors_not_in_planon)/len(b)*100,3),'%')


AP000-L99/M303, AP000-L99/M308, AP080-L79/M001, AP080-L80/M001, AP080-L81/M001, MC000-L99/M201, MC000-L99/M202, MC000-L99/M203, MC000-L99/M506, MC001-L82/M972, MC001-L82/M973, MC001-L82/M974, MC001-L82/M975, MC001-L82/M976, MC001-L99/M100, MC001-L99/M222, MC001-L99/M224, MC001-L99/M306, MC001-L99/M508, MC003-L99/M207, MC003-L99/M304, MC003-L99/M509, MC007-L99/M211, MC007-L99/M511, MC008-L82/M916, MC008-L99/M302, MC010-L82/M745, MC010-L82/M746, MC010-L82/M747, MC010-L82/M748, MC010-L82/M749, MC010-L82/M750, MC010-L82/M751, MC010-L82/M752, MC010-L82/M753, MC010-L82/M754, MC010-L82/M755, MC010-L82/M756, MC010-L82/M757, MC010-L82/M758, MC010-L82/M759, MC010-L82/M760, MC010-L82/M761, MC010-L82/M762, MC010-L82/M763, MC010-L82/M764, MC010-L82/M765, MC010-L82/M766, MC010-L82/M767, MC010-L82/M768, MC010-L82/M769, MC010-L82/M770, MC010-L82/M771, MC010-L82/M772, MC011-L82/M953, MC011-L82/M954, MC032-L82/M773, MC032-L82/M774, MC033-L82/M898, MC033-L82/M899, MC044-L82/M794, MC044-L82/M795, MC044-L82/M796, MC044-L82/M797, MC044-L82/M798, MC044-L82/M799, MC044-L82/M800, MC044-L82/M801, MC044-L82/M802, MC044-L82/M803, MC044-L82/M804, MC044-L82/M805, MC044-L82/M806, MC044-L82/M807, MC044-L82/M808, MC044-L82/M809, MC044-L82/M810, MC044-L82/M811, MC044-L82/M812, MC044-L82/M813, MC044-L82/M814, MC044-L82/M815, MC044-L82/M816, MC044-L82/M817, MC044-L82/M818, MC044-L82/M819, MC044-L82/M820, MC044-L82/M821, MC044-L82/M822, MC044-L82/M823, MC044-L82/M824, MC044-L82/M825, MC044-L82/M826, MC044-L82/M827, MC044-L82/M828, MC044-L82/M829, MC044-L82/M830, MC044-L82/M831, MC044-L82/M832, MC044-L82/M833, MC044-L82/M834, MC044-L82/M835, MC044-L82/M836, MC044-L82/M837, MC044-L82/M838, MC044-L82/M839, MC044-L82/M840, MC044-L82/M841, MC044-L82/M842, MC044-L82/M843, MC044-L82/M844, MC045-L82/M775, MC045-L82/M776, MC045-L82/M777, MC045-L82/M778, MC045-L82/M779, MC045-L82/M780, MC045-L82/M781, MC045-L82/M782, MC045-L82/M783, MC045-L82/M784, MC045-L82/M785, MC045-L82/M786, MC045-L82/M787, MC045-L82/M788, MC045-L82/M789, MC045-L82/M790, MC045-L82/M791, MC045-L82/M792, MC045-L82/M793, MC045-L82/M947, MC045-L82/M948, MC045-L82/M949, MC045-L82/M950, MC045-L82/M951, MC045-L82/M952, MC046-L82/M736, MC046-L82/M737, MC046-L82/M738, MC046-L82/M739, MC046-L82/M740, MC046-L82/M741, MC046-L82/M742, MC046-L82/M743, MC046-L82/M744, MC047-L02/M888, MC061-L99/M305, MC061-L99/M310, MC063-L82/M955, MC065-L82/M900, MC065-L82/M901, MC065-L82/M902, MC065-L82/M903, MC065-L82/M904, MC065-L82/M905, MC065-L82/M906, MC065-L82/M907, MC065-L82/M908, MC065-L82/M909, MC065-L82/M910, MC065-L82/M911, MC065-L82/M912, MC065-L82/M913, MC065-L82/M914, MC065-L82/M915, MC065-L82/M935, MC065-L82/M936, MC065-L82/M937, MC070-L82/M932, MC070-L82/M933, MC070-L82/M934, MC070-L82/M960, MC070-L82/M961, MC070-L82/M962, MC070-L82/M963, MC070-L82/M964, MC070-L82/M965, MC070-L82/M966, MC070-L82/M967, MC070-L82/M968, MC070-L82/M969, MC070-L82/M970, MC070-L82/M971, MC071-L82/M917, MC071-L82/M918, MC071-L82/M919, MC071-L82/M920, MC071-L82/M921, MC072-L82/M928, MC075-L82/M942, MC075-L82/M943, MC075-L82/M944, MC075-L82/M945, MC075-L82/M946, MC102-L82/M700, MC102-L82/M701, MC102-L82/M702, MC102-L82/M703, MC102-L82/M704, MC102-L82/M705, MC102-L82/M706, MC102-L82/M707, MC102-L82/M708, MC102-L82/M709, MC102-L82/M710, MC102-L82/M711, MC102-L82/M712, MC102-L82/M713, MC102-L82/M714, MC102-L82/M715, MC102-L82/M716, MC102-L82/M717, MC102-L82/M718, MC102-L82/M719, MC102-L82/M866, MC102-L82/M867, MC102-L82/M868, MC102-L82/M869, MC102-L82/M870, MC102-L82/M871, MC102-L82/M872, MC102-L82/M873, MC102-L82/M874, MC102-L82/M875, MC102-L82/M876, MC102-L82/M877, MC102-L82/M878, MC102-L82/M879, MC102-L82/M880, MC102-L82/M881, MC102-L82/M882, MC102-L82/M883, MC102-L82/M884, MC102-L82/M885, MC102-L82/M886, MC102-L82/M887, MC102-L99/M309, MC103-L99/M216, MC103-L99/M300, MC103-L99/M504, MC125-L82/M929, MC126-L82/M930, MC126-L82/M931, MC128-L82/M926, MC128-L82/M927, MC129-L82/M922, MC129-L82/M923, MC131-L82/M924, MC131-L82/M925, MC197-L82/M888, MC197-L82/M889, MC197-L82/M890, MC197-L82/M891, MC197-L82/M892, MC197-L82/M893, MC197-L82/M894, MC197-L82/M895, MC197-L82/M896, MC197-L82/M897, MC200-L82/M938, MC200-L82/M939, MC200-L82/M940, MC200-L82/M941, MC204-L82/M956, MC204-L82/M957, MC204-L82/M958, MC204-L82/M959, MC204-L99/M312, MC207-L82/M845, MC207-L82/M846, MC207-L82/M847, MC207-L82/M848, MC207-L82/M849, MC207-L82/M850, MC207-L82/M851, MC207-L82/M852, MC207-L82/M853, MC207-L82/M854, MC207-L82/M855, MC207-L82/M856, MC207-L82/M857, MC210-L01/M001, MC210-L01/M002, MC210-L01/M003, MC210-L01/M004, MC210-L01/M005, MC210-L01/M006, MC210-L01/M007, MC210-L01/M008, MC210-L01/M009, MC210-L01/M010, MC210-L01/M011, MC210-L01/M012, MC210-L01/M013, MC210-L01/M014, MC210-L01/M015, MC210-L01/M016, MC210-L01/M017, MC210-L01/M018, MC210-L01/M019, MC210-L01/M020, MC210-L01/M021, MC210-L01/M022, MC210-L01/M023, MC210-L01/M024, MC210-L01/M025, MC210-L01/M026, MC210-L01/M027, MC210-L01/M028, MC210-L01/M029, MC210-L01/M030, MC210-L02/M001, MC210-L02/M002, MC210-L02/M003, MC210-L02/M004, MC210-L02/M005, MC210-L02/M006, MC210-L02/M007, MC210-L02/M008, MC210-L02/M009, MC210-L02/M010, MC210-L02/M011, MC210-L02/M012, MC210-L02/M013, MC210-L02/M014, MC210-L02/M015, MC210-L02/M016, MC210-L02/M017, MC210-L02/M018, MC210-L02/M019, MC210-L02/M020, MC210-L02/M021, MC210-L02/M022, MC210-L02/M023, MC210-L82/M720, MC210-L82/M721, MC210-L82/M722, MC210-L82/M723, MC210-L82/M724, MC210-L82/M725, MC210-L82/M726, MC210-L82/M727, MC210-L82/M728, MC210-L82/M729, MC210-L82/M730, MC210-L82/M731, MC210-L82/M732, MC210-L82/M733, MC210-L82/M734, MC210-L82/M735, MC211-L82/M858, MC211-L82/M859, MC211-L82/M860, MC211-L82/M861, MC211-L82/M862, MC211-L82/M863, MC211-L82/M864, MC211-L82/M865, OC004-L99/M206, OC004-L99/M512, OC005-L99/M204, OC005-L99/M505, OC006-L99/M200, OC006-L99/M503, 

Meters in Master, but not in Planon: 364 / 29188 : 1.247 %

In [531]:
(set([i[:5] for i in meterssensors_not_in_planon]))


Out[531]:
{'AP000',
 'AP080',
 'MC000',
 'MC001',
 'MC003',
 'MC007',
 'MC008',
 'MC010',
 'MC011',
 'MC032',
 'MC033',
 'MC044',
 'MC045',
 'MC046',
 'MC047',
 'MC061',
 'MC063',
 'MC065',
 'MC070',
 'MC071',
 'MC072',
 'MC075',
 'MC102',
 'MC103',
 'MC125',
 'MC126',
 'MC128',
 'MC129',
 'MC131',
 'MC197',
 'MC200',
 'MC204',
 'MC207',
 'MC210',
 'MC211',
 'OC004',
 'OC005',
 'OC006'}

In [532]:
a=np.sort(list(set(planon_meterssensors_filtered.index)))
b=np.sort(list(set(master_meterssensors_for_validation_filtered.index)))
meterssensors_not_in_master=[]
for i in a:
    if i not in b:
        print(i+',',end=" "),
        meterssensors_not_in_master.append(i)
print('\n\nMeters in Planon, not in Master:',
      len(meterssensors_not_in_master),'/',len(a),':',
      round(len(meterssensors_not_in_master)/len(a)*100,3),'%')



Meters in Planon, not in Master: 0 / 28824 : 0.0 %

In [533]:
len(set([i for i in meterssensors_not_in_master]))


Out[533]:
0

In [534]:
set([i[:9] for i in meterssensors_not_in_master])


Out[534]:
set()

In [535]:
set([i[:5] for i in meterssensors_not_in_master])


Out[535]:
set()

Check for duplicates in index, but not duplicates over the entire row


In [536]:
print(len(planon_meterssensors_filtered.index))
print(len(set(planon_meterssensors_filtered.index)))
print(len(master_meterssensors_for_validation_filtered.index))
print(len(set(master_meterssensors_for_validation_filtered.index)))


28824
28824
29188
29188

In [537]:
master_meterssensors_for_validation_filtered[master_meterssensors_for_validation_filtered.index.duplicated()]


Out[537]:
Fiscal meter Logger Channel Code Tenant meter Description Building Name Building Code

The duplicates are the nans. Remove these for now. Could revisit later to do an index-less comparison, only over row contents.


In [538]:
good_index=[i for i in master_meterssensors_for_validation_filtered.index if str(i).lower().strip()!='nan']
master_meterssensors_for_validation_filtered=master_meterssensors_for_validation_filtered.loc[good_index]
master_meterssensors_for_validation_filtered.drop_duplicates(inplace=True)

In [539]:
len(planon_meterssensors_filtered)


Out[539]:
28824

In [540]:
len(master_meterssensors_for_validation_filtered)


Out[540]:
29188

Do comparison only on common indices. Need to revisit and identify the cause missing meters, both ways (5 Planon->Meters and 30 Meters->Planon in this example).


In [541]:
comon_index=list(set(master_meterssensors_for_validation_filtered.index).intersection(set(planon_meterssensors_filtered.index)))

In [542]:
len(comon_index)


Out[542]:
28824

In [543]:
master_meterssensors_for_validation_intersected=master_meterssensors_for_validation_filtered.loc[comon_index].sort_index()
planon_meterssensors_intersected=planon_meterssensors_filtered.loc[comon_index].sort_index()

In [544]:
len(master_meterssensors_for_validation_intersected)


Out[544]:
28824

In [545]:
len(planon_meterssensors_intersected)


Out[545]:
28824

Still have duplicate indices. For now we just drop and keep the first.


In [546]:
master_meterssensors_for_validation_intersected = master_meterssensors_for_validation_intersected[~master_meterssensors_for_validation_intersected.index.duplicated(keep='first')]

In [547]:
master_meterssensors_for_validation_intersected.head(2)


Out[547]:
Fiscal meter Logger Channel Code Tenant meter Description Building Name Building Code
AP000-L01/M001 False 1 AP000-L01/M001 False NaN Alexandra Park AP000
AP000-L02/M001 False 1 AP000-L02/M001 False Graduate House 1-11 Alexandra Park AP000

In [548]:
planon_meterssensors_intersected.head(2)


Out[548]:
Fiscal meter Logger Channel Code Tenant meter Description Building Name Building Code
AP000-L01/M001 False 1 AP000-L01/M001 False NaN Alexandra Park AP000
AP000-L02/M001 False 1 AP000-L02/M001 False Graduate House 1-11 Alexandra Park AP000

2.1.2. Primitive comparison


In [549]:
planon_meterssensors_intersected==master_meterssensors_for_validation_intersected


Out[549]:
Fiscal meter Logger Channel Code Tenant meter Description Building Name Building Code
AP000-L01/M001 True True True True False True True
AP000-L02/M001 True True True True True True True
AP000-L02/M002 True True True True True True True
AP000-L03/M001 True True True True False True True
AP000-L03/M002 True True True True False True True
AP001-L01/M001 True True True True False False True
AP001-L01/M002 True True True True False False True
AP001-L01/M003 True True True True False False True
AP001-L01/M004 True True True True False False True
AP001-L01/M005 True True True True True False True
AP001-L01/M006 True True True True True False True
AP009-L01/M001 True True True True True False True
AP009-L01/M002 True True True True True False True
AP009-L01/M003 True True True True False False True
AP010-L01/M001 True True True True True False True
AP010-L01/M002 True True True True True False True
AP010-L01/M003 True True True True True False True
AP010-L01/M004 True True True True True False True
AP010-L01/M005 True True True True True False True
AP011-L01/M001 True True True True True False True
AP011-L01/M002 True True True True True False True
AP011-L01/M003 True True True True True False True
AP011-L01/M004 True True True True True False True
AP057-L01/M001 True True True True False True True
AP057-L01/M002 True True True True True True True
AP057-L01/M003 True True True True True True True
AP080-L01/M001 True True True True False True True
AP080-L01/M002 True True True True True True True
AP080-L01/M003 True True True True True True True
AP081-L01/M001 True True True True False True True
... ... ... ... ... ... ... ...
OC006-B01/S21 True True True True True True True
OC006-B01/S22 True True True True True True True
OC006-B01/S23 True True True True True True True
OC006-B01/S24 True True True True True True True
OC006-B01/S25 True True True True True True True
OC006-B01/S26 True True True True True True True
OC006-B01/S27 True True True True True True True
OC006-B01/S28 True True True True True True True
OC006-B01/S29 True True True True True True True
OC006-B01/S3 True True True True True True True
OC006-B01/S4 True True True True True True True
OC006-B01/S5 True True True True True True True
OC006-B01/S6 True True True True True True True
OC006-B01/S8 True True True True True True True
OC006-B01/S9 True True True True True True True
OC006-B01/V1 True True True True False True True
OC006-B01/W1 True True True True True True True
OC006-B01/W10 True True True True True True True
OC006-B01/W2 True True True True True True True
OC006-B01/W3 True True True True True True True
OC006-B01/W4 True True True True True True True
OC006-B01/W5 True True True True True True True
OC006-B01/Y1 True True True True True True True
OC006-B01/Y2 True True True True True True True
OC006-B01/Y3 True True True True True True True
OC006-B01/Y4 True True True True True True True
OC006-B01/Y5 True True True True True True True
OC006-B01/Y6 True True True True True True True
OC006-B01/Z1 True True True True True True True
OC006-B01/Z2 True True True True True True True

28824 rows × 7 columns


In [550]:
np.all(planon_meterssensors_intersected==master_meterssensors_for_validation_intersected)


Out[550]:
False

2.1.3. Horizontal comparison

Number of cells matching


In [551]:
(planon_meterssensors_intersected==master_meterssensors_for_validation_intersected).sum()


Out[551]:
Fiscal meter      28824
Logger Channel    28824
Code              28824
Tenant meter      28824
Description       27435
Building Name     28295
Building Code     28824
dtype: int64

Percentage matching


In [552]:
(planon_meterssensors_intersected==master_meterssensors_for_validation_intersected).sum()/\
len(planon_meterssensors_intersected)*100


Out[552]:
Fiscal meter      100.000000
Logger Channel    100.000000
Code              100.000000
Tenant meter      100.000000
Description        95.181099
Building Name      98.164724
Building Code     100.000000
dtype: float64

In [553]:
((planon_meterssensors_intersected==master_meterssensors_for_validation_intersected).sum()/\
len(planon_meterssensors_intersected)*100).plot(kind='bar')


Out[553]:
<matplotlib.axes._subplots.AxesSubplot at 0x21eaa287f60>

2.1.4. Vertical comparison


In [554]:
df=pd.DataFrame((planon_meterssensors_intersected.T==master_meterssensors_for_validation_intersected.T).sum())
df


Out[554]:
0
AP000-L01/M001 6
AP000-L02/M001 7
AP000-L02/M002 7
AP000-L03/M001 6
AP000-L03/M002 6
AP001-L01/M001 5
AP001-L01/M002 5
AP001-L01/M003 5
AP001-L01/M004 5
AP001-L01/M005 6
AP001-L01/M006 6
AP009-L01/M001 6
AP009-L01/M002 6
AP009-L01/M003 5
AP010-L01/M001 6
AP010-L01/M002 6
AP010-L01/M003 6
AP010-L01/M004 6
AP010-L01/M005 6
AP011-L01/M001 6
AP011-L01/M002 6
AP011-L01/M003 6
AP011-L01/M004 6
AP057-L01/M001 6
AP057-L01/M002 7
AP057-L01/M003 7
AP080-L01/M001 6
AP080-L01/M002 7
AP080-L01/M003 7
AP081-L01/M001 6
... ...
OC006-B01/S21 7
OC006-B01/S22 7
OC006-B01/S23 7
OC006-B01/S24 7
OC006-B01/S25 7
OC006-B01/S26 7
OC006-B01/S27 7
OC006-B01/S28 7
OC006-B01/S29 7
OC006-B01/S3 7
OC006-B01/S4 7
OC006-B01/S5 7
OC006-B01/S6 7
OC006-B01/S8 7
OC006-B01/S9 7
OC006-B01/V1 6
OC006-B01/W1 7
OC006-B01/W10 7
OC006-B01/W2 7
OC006-B01/W3 7
OC006-B01/W4 7
OC006-B01/W5 7
OC006-B01/Y1 7
OC006-B01/Y2 7
OC006-B01/Y3 7
OC006-B01/Y4 7
OC006-B01/Y5 7
OC006-B01/Y6 7
OC006-B01/Z1 7
OC006-B01/Z2 7

28824 rows × 1 columns


In [555]:
df=pd.DataFrame((planon_meterssensors_intersected.T==master_meterssensors_for_validation_intersected.T).sum()/\
len(planon_meterssensors_intersected.T)*100)
df[df[0]<100]


Out[555]:
0
AP000-L01/M001 85.714286
AP000-L03/M001 85.714286
AP000-L03/M002 85.714286
AP001-L01/M001 71.428571
AP001-L01/M002 71.428571
AP001-L01/M003 71.428571
AP001-L01/M004 71.428571
AP001-L01/M005 85.714286
AP001-L01/M006 85.714286
AP009-L01/M001 85.714286
AP009-L01/M002 85.714286
AP009-L01/M003 71.428571
AP010-L01/M001 85.714286
AP010-L01/M002 85.714286
AP010-L01/M003 85.714286
AP010-L01/M004 85.714286
AP010-L01/M005 85.714286
AP011-L01/M001 85.714286
AP011-L01/M002 85.714286
AP011-L01/M003 85.714286
AP011-L01/M004 85.714286
AP057-L01/M001 85.714286
AP080-L01/M001 85.714286
AP081-L01/M001 85.714286
EX001-B01/V1 85.714286
MC001-B01/V1 85.714286
MC001-L02/M001 85.714286
MC003-B01/I4 85.714286
MC003-B01/V1 85.714286
MC003-B01/V2 85.714286
... ...
MC210-B01/U2 85.714286
MC210-B01/V1 85.714286
MC210-B02/U1 85.714286
MC210-B02/U2 85.714286
MC210-B02/V1 85.714286
MC210-B03/D60 85.714286
MC210-B03/U1 85.714286
MC210-B03/U2 85.714286
MC210-B03/V1 85.714286
MC211-B01/P23 85.714286
MC211-B01/P24 85.714286
MC211-B01/S24 85.714286
MC211-B01/S25 85.714286
MC211-B01/V1 85.714286
OC004-B01/G50 85.714286
OC004-B01/L1 85.714286
OC004-B01/L2 85.714286
OC004-B01/L3 85.714286
OC004-B01/L4 85.714286
OC004-B01/V1 85.714286
OC005-B01/G50 85.714286
OC005-B01/L1 85.714286
OC005-B01/L2 85.714286
OC005-B01/L3 85.714286
OC005-B01/V1 85.714286
OC006-B01/G50 85.714286
OC006-B01/L1 85.714286
OC006-B01/L2 85.714286
OC006-B01/L3 85.714286
OC006-B01/V1 85.714286

1906 rows × 1 columns

2.1.5. Smart(er) comparison

Not all of the dataframe matches. Let us do some basic string formatting, maybe that helps.


In [556]:
sum(planon_meterssensors_intersected['Description']!=master_meterssensors_for_validation_intersected['Description'])


Out[556]:
1389

In [557]:
planon_meterssensors_intersected['Description']=[str(s).lower().strip()\
        .replace('  ',' ').replace('   ',' ').replace('nan','')\
        for s in planon_meterssensors_intersected['Description'].values]
master_meterssensors_for_validation_intersected['Description']=[str(s).lower().strip()\
        .replace('  ',' ').replace('   ',' ').replace('nan','')\
        for s in master_meterssensors_for_validation_intersected['Description'].values]

In [558]:
sum(planon_meterssensors_intersected['Description']!=master_meterssensors_for_validation_intersected['Description'])


Out[558]:
0

Some errors fixed, some left. Let's see which ones. These are either:

  • Wrong duplicate dropped
  • Input human erros in the description.
  • Actual erros somewhere in the indexing.

In [559]:
for i in planon_meterssensors_intersected[planon_meterssensors_intersected['Description']!=master_meterssensors_for_validation_intersected['Description']].index:
    print(i,'\t\tPlanon:',planon_meterssensors_intersected.loc[i]['Description'],'\t\tMaster:',master_meterssensors_for_validation_intersected.loc[i]['Description'])

Let us repeat the exercise for Logger Channel. Cross-validate, flag as highly likely error where both mismatch.


In [560]:
sum(planon_meterssensors_intersected['Logger Channel']!=master_meterssensors_for_validation_intersected['Logger Channel'])


Out[560]:
0

In [561]:
planon_meterssensors_intersected['Logger Channel']=[str(s).lower().strip().replace('  ',' ').replace('   ',' ') for s in planon_meterssensors_intersected['Logger Channel'].values]
master_meterssensors_for_validation_intersected['Logger Channel']=[str(s).lower().strip().replace('  ',' ').replace('   ',' ') for s in master_meterssensors_for_validation_intersected['Logger Channel'].values]

In [562]:
sum(planon_meterssensors_intersected['Logger Channel']!=master_meterssensors_for_validation_intersected['Logger Channel'])


Out[562]:
0

All errors fixed on logger channels.


In [563]:
for i in planon_meterssensors_intersected[planon_meterssensors_intersected['Logger Channel']!=master_meterssensors_for_validation_intersected['Logger Channel']].index:
    print(i,'\t\tPlanon:',planon_meterssensors_intersected.loc[i]['Logger Channel'],'\t\tMaster:',master_meterssensors_for_validation_intersected.loc[i]['Logger Channel'])

New error percentage:


In [564]:
(planon_meterssensors_intersected!=master_meterssensors_for_validation_intersected).sum()/\
len(planon_meterssensors_intersected)*100


Out[564]:
Fiscal meter      0.000000
Logger Channel    0.000000
Code              0.000000
Tenant meter      0.000000
Description       0.000000
Building Name     1.835276
Building Code     0.000000
dtype: float64

2.2. Loggers


In [565]:
buildings=set(planon_loggerscontrollers['BuildingNo.'])
buildings


Out[565]:
{'AP000',
 'AP001',
 'AP009',
 'AP010',
 'AP011',
 'AP057',
 'AP080',
 'AP081',
 'EX000',
 'EX001',
 'EX005',
 'FH000',
 'FH002',
 'FH003',
 'FH008',
 'FH012',
 'MC000',
 'MC001',
 'MC002',
 'MC003',
 'MC007',
 'MC008',
 'MC010',
 'MC011',
 'MC013',
 'MC014',
 'MC029',
 'MC030',
 'MC031',
 'MC032',
 'MC033',
 'MC042',
 'MC043',
 'MC044',
 'MC045',
 'MC046',
 'MC047',
 'MC048',
 'MC050',
 'MC051',
 'MC053',
 'MC055',
 'MC060',
 'MC061',
 'MC062',
 'MC063',
 'MC064',
 'MC065',
 'MC066',
 'MC067',
 'MC068',
 'MC069',
 'MC070',
 'MC071',
 'MC072',
 'MC075',
 'MC076',
 'MC077',
 'MC078',
 'MC083',
 'MC095',
 'MC099',
 'MC102',
 'MC103',
 'MC125',
 'MC126',
 'MC128',
 'MC129',
 'MC131',
 'MC134',
 'MC138',
 'MC139',
 'MC140',
 'MC141',
 'MC171',
 'MC181',
 'MC197',
 'MC198',
 'MC199',
 'MC200',
 'MC202',
 'MC203',
 'MC204',
 'MC207',
 'MC210',
 'MC211',
 'OC001',
 'OC003',
 'OC004',
 'OC005',
 'OC006',
 'OC007',
 'OC008',
 'OC011',
 'OC012'}

In [566]:
master_loggerscontrollers_for_validation = \
    pd.concat([master_loggerscontrollers.loc[master_loggerscontrollers['Building Code'] == building] \
           for building in buildings])
master_loggerscontrollers_for_validation.head(2)


Out[566]:
Building Code Building Name Space Description Classification Group Make Model Logger Serial Number Logger Mac Address Logger Ip Address Logger Modem Serial Number Logger Sim Network Point Id Logger Upstream Comms Target Additional Location Info Code
MC095-L01 MC095 Pendle College, Kelbrook (12) L1 Data logger: Pendle Laundry Data logger Enercom Multilog G2 050157A5E400 00-50-C2-2C-3E-2D 10.23.11.9 NaN NaN NaN NaN Mains Room MC095-L01
MC138-L01 MC138 Sub Station 7 SS Data logger: Substation No.7 Data logger Enercom Multilog G2 05019838EB00 NaN NaN NaN NaN NaN NaN A017 MC138-L01

In [567]:
len(master_loggerscontrollers_for_validation)


Out[567]:
378

In [568]:
len(planon_loggerscontrollers)-len(planon_loggerscontrollers.index[planon_loggerscontrollers.index.duplicated()])


Out[568]:
359

In [569]:
master_loggerscontrollers_for_validation.sort_index(inplace=True)
planon_loggerscontrollers.sort_index(inplace=True)


C:\Anaconda2\envs\python3\lib\site-packages\ipykernel\__main__.py:2: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  from ipykernel import kernelapp as app

In [570]:
planon_loggerscontrollers.T


Out[570]:
AP000-L01 AP000-L02 AP000-L03 AP000-L99 AP001-L01 AP009-L01 AP010-L01 AP011-L01 AP057-L01 AP080-L01 ... OC004-B01 OC004-L99 OC005-B01 OC005-L99 OC006-B01 OC006-L99 OC007-L99 OC008-L99 OC011-L99 OC012-L99
BuildingNo. AP000 AP000 AP000 AP000 AP001 AP009 AP010 AP011 AP057 AP080 ... OC004 OC004 OC005 OC005 OC006 OC006 OC007 OC008 OC011 OC012
Building Alexandra Park Alexandra Park Alexandra Park Alexandra Park House 01 - Bassenthwaite, Graduate College House 09 - Devoke, Graduate College House 10 - Elterwater, Graduate College House 11 - Ennerdale, Graduate College Alexandra Park Laundrette Lonsdale House (Block 12) ... Chancellor's Wharf, Wyre House Chancellor's Wharf, Wyre House Chancellor's Wharf, Lune House Chancellor's Wharf, Lune House Chancellor's Wharf, Kent House Chancellor's Wharf, Kent House Hazelrigg Field Station Downings Wind Turbine North Lodge Cottage
Locations.Space.Space number A0 A0 A0 NaN A104 A124 A109 A102 A0 A13 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Space Name Whole Site Whole Site Whole Site NaN Electrical Riser Electrical Riser/Cupboard Electrical Riser Electrical Riser Whole Building Laundrette ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Additional Location Info NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Description Data logger: Alexandra Park Data logger: Alexandra Park Data logger: Alexandra Park Data logger: Alexandra Park Data logger: Graduate College - House 1 Data logger: Graduate College - House 9 Data logger: Graduate College - House 10 Data logger: Graduate College - House 11 Data logger: Alexandra Park Laundrette Data logger: Lonsdale House - Laundrette ... BMS Controller: Chancellors Wharf Data logger: Chancellor's Wharf, Wyre House BMS Controller: Chancellors Wharf Data logger: Chancellor's Wharf, Lune House BMS Controller: Chancellors Wharf Data logger: Chancellor's Wharf, Kent House Data logger: Hazelrigg Field Station Data logger: Downings Data logger: Wind Turbine Data logger: North Lodge Cottage
Classification Group EN.EN1 Data Logger EN.EN1 Data Logger EN.EN1 Data Logger EN.EN1 Data Logger EN.EN1 Data Logger EN.EN1 Data Logger EN.EN1 Data Logger EN.EN1 Data Logger EN.EN1 Data Logger EN.EN1 Data Logger ... EN.EN4 BMS Controller EN.EN1 Data Logger EN.EN4 BMS Controller EN.EN1 Data Logger EN.EN4 BMS Controller EN.EN1 Data Logger EN.EN1 Data Logger EN.EN1 Data Logger EN.EN1 Data Logger EN.EN1 Data Logger
Record NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
HVAC Ref NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Element Description NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Servicable Area NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Model Multilog G2 Multilog G2 Multilog G2 NaN Multilog G2 Multilog G2 Multilog G2 Multilog G2 Multilog G2 Multilog G2 ... IQ3xact12 NaN IQ3xact12 NaN IQ3xact12 NaN NaN NaN NaN NaN
Make Enercom Enercom Enercom NaN Enercom Enercom Enercom Enercom Enercom Enercom ... Trend NaN Trend NaN Trend NaN NaN NaN NaN NaN
EIS ID 050157C7ED00 37475126 48015355 NaN 0501E3E97100 0501E38A6300 0501E3D07500 0501E3839500 050157C16100 050157AB6700 ... {48352BB4-4B1B-4013-AB9F-14E143E83948} NaN {281682DC-5479-4064-8290-E873933872B0} NaN {BBD3685B-B0DC-417F-A0E8-20139B1074E1} NaN NaN NaN NaN NaN
Logger Channel 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
Logger Upstream Comms Target NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Logger Modem Serial Number NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Logger IP Address 10.23.9.39 NaN NaN NaN 10.23.12.36 NaN 10.23.12.37 10.23.12.38 80.93.175.91:40455 10.23.9.40 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Logger Serial Number NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Logger MAC Address 00-50-C2-2C-3E-43 NaN NaN NaN 00-50-C2-2C-3D-DE 00-50-C2-2C-3D-CB 00-50-C2-2C-3D-D1 00-50-C2-2C-3D-A7 NaN 00-50-C2-2C-3D-1B ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Logger SIM NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Meter Pulse Value NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Meter Units NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Meter Capacity NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Network Point ID NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Tenant Meter.Name NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Fiscal Meter.Name NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
EIS Space.Space number NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Utility Type.Name NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Code AP000-L01 AP000-L02 AP000-L03 AP000-L99 AP001-L01 AP009-L01 AP010-L01 AP011-L01 AP057-L01 AP080-L01 ... OC004-B01 OC004-L99 OC005-B01 OC005-L99 OC006-B01 OC006-L99 OC007-L99 OC008-L99 OC011-L99 OC012-L99

30 rows × 359 columns


In [571]:
master_loggerscontrollers_for_validation.T


Out[571]:
AP000-L01 AP000-L02 AP000-L03 AP000-L99 AP001-L01 AP009-L01 AP010-L01 AP011-L01 AP057-L01 AP080-L01 ... OC004-B01 OC004-L99 OC005-B01 OC005-L99 OC006-B01 OC006-L99 OC007-L99 OC008-L99 OC011-L99 OC012-L99
Building Code AP000 AP000 AP000 AP000 AP001 AP009 AP010 AP011 AP057 AP080 ... OC004 OC004 OC005 OC005 OC006 OC006 OC007 OC008 OC011 OC012
Building Name Alexandra Park Alexandra Park Alexandra Park Alexandra Park House 01 - Bassenthwaite, Graduate College House 09 - Devoke, Graduate College House 10 - Elterwater, Graduate College House 11 - Ennerdale, Graduate College Alexandra Park Laundrette Lonsdale House (Block 12) ... Chancellors Wharf Chancellor's Wharf, Wyre House Chancellors Wharf Chancellor's Wharf, Lune House Chancellors Wharf Chancellor's Wharf, Kent House Hazelrigg Field Station Downings Wind Turbine North Lodge Cottage
Space A0 A0 A0 NaN A104 A124 A109 A102 A0 A13 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Description Data logger: Alexandra Park Data logger: Alexandra Park Data logger: Alexandra Park Data logger: Alexandra Park Data logger: Graduate College - House 1 Data logger: Graduate College - House 9 Data logger: Graduate College - House 10 Data logger: Graduate College - House 11 Data logger: Alexandra Park Laundrette Data logger: Lonsdale House - Laundrette ... BMS Controller: Chancellors Wharf Data logger: Chancellor's Wharf, Wyre House BMS Controller: Chancellors Wharf Data logger: Chancellor's Wharf, Lune House BMS Controller: Chancellors Wharf Data logger: Chancellor's Wharf, Kent House Data logger: Hazelrigg Field Station Data logger: Downings Data logger: Wind Turbine Data logger: North Lodge Cottage
Classification Group Data logger Data logger Data logger Data logger Data logger Data logger Data logger Data logger Data logger Data logger ... BMS controller Data logger BMS controller Data logger BMS controller Data logger Data logger Data logger Data logger Data logger
Make Enercom Enercom Enercom NaN Enercom Enercom Enercom Enercom Enercom Enercom ... Trend NaN Trend NaN Trend NaN NaN NaN NaN NaN
Model Multilog G2 Multilog G2 Multilog G2 NaN Multilog G2 Multilog G2 Multilog G2 Multilog G2 Multilog G2 Multilog G2 ... IQ3xact12 NaN IQ3xact12 NaN IQ3xact12 NaN NaN NaN NaN NaN
Logger Serial Number 050157C7ED00 37475126 48015355 NaN 0501E3E97100 0501E38A6300 0501E3D07500 0501E3839500 050157C16100 050157AB6700 ... {48352BB4-4B1B-4013-AB9F-14E143E83948} NaN {281682DC-5479-4064-8290-E873933872B0} NaN {BBD3685B-B0DC-417F-A0E8-20139B1074E1} NaN NaN NaN NaN NaN
Logger Mac Address 00-50-C2-2C-3E-43 NaN NaN NaN 00-50-C2-2C-3D-DE 00-50-C2-2C-3D-CB 00-50-C2-2C-3D-D1 00-50-C2-2C-3D-A7 NaN 00-50-C2-2C-3D-1B ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Logger Ip Address 10.23.9.39 NaN NaN NaN 10.23.12.36 NaN 10.23.12.37 10.23.12.38 80.93.175.91:40455 10.23.9.40 ... cw-meter03-plant.bms.local NaN cw-meter02-plant.bms.local NaN cw-meter01-plant.bms.local NaN NaN NaN NaN NaN
Logger Modem Serial Number NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Logger Sim NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Network Point Id NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Logger Upstream Comms Target NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Additional Location Info Graduatae 1-11 Plant Room External Gas Meter Building External Water Meter Chamber NaN A017 Devoke House, Room A124 Elderwater House, Room A109 Ennerdale House - Room A102 Cartmel Laundrette Plant Room MCC ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Code AP000-L01 AP000-L02 AP000-L03 AP000-L99 AP001-L01 AP009-L01 AP010-L01 AP011-L01 AP057-L01 AP080-L01 ... OC004-B01 OC004-L99 OC005-B01 OC005-L99 OC006-B01 OC006-L99 OC007-L99 OC008-L99 OC011-L99 OC012-L99

16 rows × 378 columns

Create dictionary that maps Planon column names onto Master.

From Nicola:

  • EIS ID (Serial Number)
  • Make
  • Model
  • Description
  • Code (Asset Code)
  • Building Code

Building code and Building name are implicitly included. Logger IP or MAC would be essential to include, as well as Make and Model. Additional Location Info is not essnetial but would be useful to have. Locations (Locations.Space.Space number and Space Name) are included in the Planon export - but this is their only viable data source, therefore are not validated against.


In [572]:
#Planon:Master
loggers_match_dict={
      "BuildingNo.":"Building Code",
      "Building":"Building Name",
      "Description":"Description",
      "EIS ID":"Logger Serial Number",
      "Make":"Make",
      "Model":"Model",
      "Code":"Code"
      }

In [573]:
master_loggerscontrollers_for_validation_filtered=master_loggerscontrollers_for_validation[list(loggers_match_dict.values())]
planon_loggerscontrollers_filtered=planon_loggerscontrollers[list(loggers_match_dict.keys())]

In [574]:
master_loggerscontrollers_for_validation_filtered.head(2)


Out[574]:
Code Logger Serial Number Make Model Description Building Name Building Code
AP000-L01 AP000-L01 050157C7ED00 Enercom Multilog G2 Data logger: Alexandra Park Alexandra Park AP000
AP000-L02 AP000-L02 37475126 Enercom Multilog G2 Data logger: Alexandra Park Alexandra Park AP000

In [575]:
planon_loggerscontrollers_filtered.head(2)


Out[575]:
Code EIS ID Make Model Description Building BuildingNo.
AP000-L01 AP000-L01 050157C7ED00 Enercom Multilog G2 Data logger: Alexandra Park Alexandra Park AP000
AP000-L02 AP000-L02 37475126 Enercom Multilog G2 Data logger: Alexandra Park Alexandra Park AP000

In [576]:
planon_loggerscontrollers_filtered.columns=[loggers_match_dict[i] for i in planon_loggerscontrollers_filtered]

In [577]:
planon_loggerscontrollers_filtered.drop_duplicates(inplace=True)
master_loggerscontrollers_for_validation_filtered.drop_duplicates(inplace=True)


C:\Anaconda2\envs\python3\lib\site-packages\pandas\util\decorators.py:91: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  return func(*args, **kwargs)

In [578]:
planon_loggerscontrollers_filtered.head(2)


Out[578]:
Code Logger Serial Number Make Model Description Building Name Building Code
AP000-L01 AP000-L01 050157C7ED00 Enercom Multilog G2 Data logger: Alexandra Park Alexandra Park AP000
AP000-L02 AP000-L02 37475126 Enercom Multilog G2 Data logger: Alexandra Park Alexandra Park AP000

In [579]:
master_loggerscontrollers_for_validation_filtered.head(2)


Out[579]:
Code Logger Serial Number Make Model Description Building Name Building Code
AP000-L01 AP000-L01 050157C7ED00 Enercom Multilog G2 Data logger: Alexandra Park Alexandra Park AP000
AP000-L02 AP000-L02 37475126 Enercom Multilog G2 Data logger: Alexandra Park Alexandra Park AP000

In [580]:
a=np.sort(list(set(planon_loggerscontrollers_filtered.index)))
b=np.sort(list(set(master_loggerscontrollers_for_validation_filtered.index)))
loggerscontrollers_not_in_planon=[]
for i in b:
    if i not in a:
        print(i+',',end=" "),
        loggerscontrollers_not_in_planon.append(i)
print('\n\nLoggers in Master, but not in Planon:',
      len(loggerscontrollers_not_in_planon),'/',len(b),':',
      round(len(loggerscontrollers_not_in_planon)/len(b)*100,3),'%')


MC032-L01, MC032-L03, MC044-L02, MC044-L03, MC044-L04, MC044-L05, MC046-L01, MC046-L03, MC046-L04, MC061-L01, MC076-B03, MC202-B17, MC202-L04, MC204-L03, MC204-L04, MC204-L07, MC204-L08, MC204-L09, MC207-L01, 

Loggers in Master, but not in Planon: 19 / 378 : 5.026 %

In [581]:
a=np.sort(list(set(planon_loggerscontrollers_filtered.index)))
b=np.sort(list(set(master_loggerscontrollers_for_validation_filtered.index)))
loggerscontrollers_not_in_master=[]
for i in a:
    if i not in b:
        print(i+',',end=" "),
        loggerscontrollers_not_in_master.append(i)
print('\n\nLoggers in Planon, not in Master:',
      len(loggerscontrollers_not_in_master),'/',len(a),':',
      round(len(loggerscontrollers_not_in_master)/len(a)*100,3),'%')



Loggers in Planon, not in Master: 0 / 359 : 0.0 %

In [582]:
print(len(planon_loggerscontrollers_filtered.index))
print(len(set(planon_loggerscontrollers_filtered.index)))
print(len(master_loggerscontrollers_for_validation_filtered.index))
print(len(set(master_loggerscontrollers_for_validation_filtered.index)))


359
359
378
378

In [583]:
master_loggerscontrollers_for_validation_filtered[master_loggerscontrollers_for_validation_filtered.index.duplicated()]


Out[583]:
Code Logger Serial Number Make Model Description Building Name Building Code

In [584]:
comon_index=list(set(master_loggerscontrollers_for_validation_filtered.index).intersection(set(planon_loggerscontrollers_filtered.index)))

In [585]:
master_loggerscontrollers_for_validation_intersected=master_loggerscontrollers_for_validation_filtered.loc[comon_index].sort_index()
planon_loggerscontrollers_intersected=planon_loggerscontrollers_filtered.loc[comon_index].sort_index()

In [586]:
master_loggerscontrollers_for_validation_intersected.head(2)


Out[586]:
Code Logger Serial Number Make Model Description Building Name Building Code
AP000-L01 AP000-L01 050157C7ED00 Enercom Multilog G2 Data logger: Alexandra Park Alexandra Park AP000
AP000-L02 AP000-L02 37475126 Enercom Multilog G2 Data logger: Alexandra Park Alexandra Park AP000

In [587]:
planon_loggerscontrollers_intersected.head(2)


Out[587]:
Code Logger Serial Number Make Model Description Building Name Building Code
AP000-L01 AP000-L01 050157C7ED00 Enercom Multilog G2 Data logger: Alexandra Park Alexandra Park AP000
AP000-L02 AP000-L02 37475126 Enercom Multilog G2 Data logger: Alexandra Park Alexandra Park AP000

In [588]:
planon_loggerscontrollers_intersected==master_loggerscontrollers_for_validation_intersected


Out[588]:
Code Logger Serial Number Make Model Description Building Name Building Code
AP000-L01 True True True True True True True
AP000-L02 True False True True True True True
AP000-L03 True False True True True True True
AP000-L99 True False False False True True True
AP001-L01 True True True True True True True
AP009-L01 True True True True True True True
AP010-L01 True True True True True True True
AP011-L01 True True True True True True True
AP057-L01 True True True True True True True
AP080-L01 True True True True True True True
AP080-L79 True False False False True True True
AP080-L80 True False False False True True True
AP080-L81 True False False False True True True
AP081-L01 True True True True True True True
EX000-L99 True False False False True True True
EX001-B01 True True True True True False True
EX005-L99 True False False False True True True
FH000-L99 True False False False True True True
FH002-L99 True False False False True True True
FH003-L99 True False False False True True True
FH008-L99 True False False False True True True
FH012-L99 True False False False True True True
MC000-L01 True True True True True True True
MC000-L99 True False False False True True True
MC001-B01 True True True True True True True
MC001-L01 True True True True True True True
MC001-L02 True True True True True True True
MC001-L82 True False False False True True True
MC001-L99 True False False False True True True
MC002-L99 True False False False True True True
... ... ... ... ... ... ... ...
MC204-L06 True True True True True True True
MC204-L73 True True True True True True True
MC204-L74 True True True True True True True
MC204-L75 True True True True True True True
MC204-L82 True False False False True True True
MC204-L99 True True True True True True True
MC207-B01 True True True True True True True
MC207-L52 True True True True True True True
MC207-L53 True True True True True True True
MC207-L82 True False False False True True True
MC210-B01 True True True True True True True
MC210-B02 True True True True True True True
MC210-B03 True True True True True True True
MC210-L01 True False True True True True True
MC210-L02 True False True True True True True
MC210-L82 True False False False True True True
MC211-B01 True True True True True True True
MC211-L82 True False False False True True True
OC001-L99 True False False False True True True
OC003-L99 True False False False True True True
OC004-B01 True True True True True False True
OC004-L99 True False False False True True True
OC005-B01 True True True True True False True
OC005-L99 True False False False True True True
OC006-B01 True True True True True False True
OC006-L99 True False False False True True True
OC007-L99 True False False False True True True
OC008-L99 True False False False True True True
OC011-L99 True False False False True True True
OC012-L99 True False False False True True True

359 rows × 7 columns

Loggers matching


In [589]:
(planon_loggerscontrollers_intersected==master_loggerscontrollers_for_validation_intersected).sum()


Out[589]:
Code                    359
Logger Serial Number    288
Make                    302
Model                   302
Description             359
Building Name           341
Building Code           359
dtype: int64

Percentage matching


In [590]:
(planon_loggerscontrollers_intersected==master_loggerscontrollers_for_validation_intersected).sum()/\
len(planon_loggerscontrollers_intersected)*100


Out[590]:
Code                    100.000000
Logger Serial Number     80.222841
Make                     84.122563
Model                    84.122563
Description             100.000000
Building Name            94.986072
Building Code           100.000000
dtype: float64

In [591]:
((planon_loggerscontrollers_intersected==master_loggerscontrollers_for_validation_intersected).sum()/\
len(planon_loggerscontrollers_intersected)*100).plot(kind='bar')


Out[591]:
<matplotlib.axes._subplots.AxesSubplot at 0x21eb6468b38>

Loggers not matching on Building Name.


In [592]:
sum(planon_loggerscontrollers_intersected['Building Name']!=master_loggerscontrollers_for_validation_intersected['Building Name'])


Out[592]:
18

In [593]:
planon_loggerscontrollers_intersected['Building Name']=[str(s).lower().strip().replace('  ',' ').replace('   ',' ') for s in planon_loggerscontrollers_intersected['Building Name'].values]
master_loggerscontrollers_for_validation_intersected['Building Name']=[str(s).lower().strip().replace('  ',' ').replace('   ',' ') for s in master_loggerscontrollers_for_validation_intersected['Building Name'].values]

In [594]:
sum(planon_loggerscontrollers_intersected['Building Name']!=master_loggerscontrollers_for_validation_intersected['Building Name'])


Out[594]:
16

That didnt help.


In [595]:
for i in planon_loggerscontrollers_intersected[planon_loggerscontrollers_intersected['Building Name']!=master_loggerscontrollers_for_validation_intersected['Building Name']].index:
    print(i,'\t\tPlanon:',planon_loggerscontrollers_intersected.loc[i]['Building Name'],'\t\tMaster:',master_loggerscontrollers_for_validation_intersected.loc[i]['Building Name'])


EX001-B01 		Planon: roads - main campus 		Master: underpass
MC029-B01 		Planon: cetad 		Master: bowland hall cetad
MC033-L03 		Planon: county john creed 		Master: john creed
MC047-B02 		Planon: welcome centre 		Master: conference centre
MC047-L01 		Planon: welcome centre 		Master: conference centre
MC047-L02 		Planon: welcome centre 		Master: conference centre
MC055-B01 		Planon: furness residences 		Master: furness blocks
MC071-B01 		Planon: furness college 		Master: furness
MC072-B02 		Planon: psc 		Master: psc building
MC072-B04 		Planon: psc 		Master: psc building
MC103-B01 		Planon: lancaster house hotel 		Master: hotel
MC198-B01 		Planon: grizedale college - offices, bar & social space 		Master: grizedale
MC198-B02 		Planon: grizedale college - offices, bar & social space 		Master: grizedale
OC004-B01 		Planon: chancellor's wharf, wyre house 		Master: chancellors wharf
OC005-B01 		Planon: chancellor's wharf, lune house 		Master: chancellors wharf
OC006-B01 		Planon: chancellor's wharf, kent house 		Master: chancellors wharf

Follow up with lexical distance comparison. That would flag this as a match.

Loggers not matching on Serial Number.


In [596]:
sum(planon_loggerscontrollers_intersected['Logger Serial Number']!=master_loggerscontrollers_for_validation_intersected['Logger Serial Number'])


Out[596]:
71

In [597]:
planon_loggerscontrollers_intersected['Logger Serial Number']=[str(s).lower().strip().replace('  ',' ').replace('   ',' ').replace('{','').replace('}','') for s in planon_loggerscontrollers_intersected['Logger Serial Number'].values]
master_loggerscontrollers_for_validation_intersected['Logger Serial Number']=[str(s).lower().strip().replace('  ',' ').replace('   ',' ').replace('{','').replace('}','') for s in master_loggerscontrollers_for_validation_intersected['Logger Serial Number'].values]

In [598]:
sum(planon_loggerscontrollers_intersected['Logger Serial Number']!=master_loggerscontrollers_for_validation_intersected['Logger Serial Number'])


Out[598]:
9

In [599]:
for i in planon_loggerscontrollers_intersected[planon_loggerscontrollers_intersected['Logger Serial Number']!=master_loggerscontrollers_for_validation_intersected['Logger Serial Number']].index:
    print(i,'\t\tPlanon:',planon_loggerscontrollers_intersected.loc[i]['Logger Serial Number'],'\t\tMaster:',master_loggerscontrollers_for_validation_intersected.loc[i]['Logger Serial Number'])


MC032-L04 		Planon: 50198367 		Master: 050198367e00
MC046-L05 		Planon: 50198895300 		Master: 050198895300
MC063-L01 		Planon: 50198829500 		Master: 050198829500
MC064-L03 		Planon: 50198872600 		Master: 050198872600
MC071-L02 		Planon: 50201286300 		Master: 050201286300
MC071-L05 		Planon: 50201221 		Master: 050201221e00
MC071-L16 		Planon: 50198904000 		Master: 050198904000
MC078-L03 		Planon: 50198864300 		Master: 050198864300
MC102-L01 		Planon: 50157909800 		Master: 050157909800

Technically the same, but there is a number format error. Compare based on float value, if they match, replace one of them. This needs to be amended, as it will throw cannot onvert to float exception if strings are left in from the previous step.


In [600]:
z1=[]
z2=[]    
for i in planon_loggerscontrollers_intersected.index:
    if planon_loggerscontrollers_intersected.loc[i]['Logger Serial Number']!=master_loggerscontrollers_for_validation_intersected.loc[i]['Logger Serial Number']:
        if float(planon_loggerscontrollers_intersected.loc[i]['Logger Serial Number'])==\
          float(master_loggerscontrollers_for_validation_intersected.loc[i]['Logger Serial Number']):
                z1.append(str(int(float(planon_loggerscontrollers_intersected.loc[i]['Logger Serial Number']))))
                z2.append(str(int(float(planon_loggerscontrollers_intersected.loc[i]['Logger Serial Number']))))
        else:
            z1.append(planon_loggerscontrollers_intersected.loc[i]['Logger Serial Number'])
            z2.append(master_loggerscontrollers_for_validation_intersected.loc[i]['Logger Serial Number'])
    else:
        z1.append(planon_loggerscontrollers_intersected.loc[i]['Logger Serial Number'])
        z2.append(planon_loggerscontrollers_intersected.loc[i]['Logger Serial Number'])
planon_loggerscontrollers_intersected['Logger Serial Number']=z1
master_loggerscontrollers_for_validation_intersected['Logger Serial Number']=z2

In [601]:
for i in planon_loggerscontrollers_intersected[planon_loggerscontrollers_intersected['Logger Serial Number']!=master_loggerscontrollers_for_validation_intersected['Logger Serial Number']].index:
    print(i,'\t\tPlanon:',planon_loggerscontrollers_intersected.loc[i]['Logger Serial Number'],'\t\tMaster:',master_loggerscontrollers_for_validation_intersected.loc[i]['Logger Serial Number'])

New error percentage:


In [602]:
(planon_loggerscontrollers_intersected!=master_loggerscontrollers_for_validation_intersected).sum()/\
len(planon_loggerscontrollers_intersected)*100


Out[602]:
Code                     0.000000
Logger Serial Number     0.000000
Make                    15.877437
Model                   15.877437
Description              0.000000
Building Name            4.456825
Building Code            0.000000
dtype: float64

(Bearing in my mind the above, this is technically 0)


In [603]:
a=np.sort(list(set(planon_meterssensors_filtered.index)))
b=np.sort(list(set(master_meterssensors_for_validation_filtered.index)))
meterssensors_not_in_planon=[]
for i in b:
    if i not in a:
        print(i+',',end=" "),
        meterssensors_not_in_planon.append(i)
print('\n\nMeters in Master, but not in Planon:',
      len(meterssensors_not_in_planon),'/',len(b),':',
      round(len(meterssensors_not_in_planon)/len(b)*100,3),'%')


AP000-L99/M303, AP000-L99/M308, AP080-L79/M001, AP080-L80/M001, AP080-L81/M001, MC000-L99/M201, MC000-L99/M202, MC000-L99/M203, MC000-L99/M506, MC001-L82/M972, MC001-L82/M973, MC001-L82/M974, MC001-L82/M975, MC001-L82/M976, MC001-L99/M100, MC001-L99/M222, MC001-L99/M224, MC001-L99/M306, MC001-L99/M508, MC003-L99/M207, MC003-L99/M304, MC003-L99/M509, MC007-L99/M211, MC007-L99/M511, MC008-L82/M916, MC008-L99/M302, MC010-L82/M745, MC010-L82/M746, MC010-L82/M747, MC010-L82/M748, MC010-L82/M749, MC010-L82/M750, MC010-L82/M751, MC010-L82/M752, MC010-L82/M753, MC010-L82/M754, MC010-L82/M755, MC010-L82/M756, MC010-L82/M757, MC010-L82/M758, MC010-L82/M759, MC010-L82/M760, MC010-L82/M761, MC010-L82/M762, MC010-L82/M763, MC010-L82/M764, MC010-L82/M765, MC010-L82/M766, MC010-L82/M767, MC010-L82/M768, MC010-L82/M769, MC010-L82/M770, MC010-L82/M771, MC010-L82/M772, MC011-L82/M953, MC011-L82/M954, MC032-L82/M773, MC032-L82/M774, MC033-L82/M898, MC033-L82/M899, MC044-L82/M794, MC044-L82/M795, MC044-L82/M796, MC044-L82/M797, MC044-L82/M798, MC044-L82/M799, MC044-L82/M800, MC044-L82/M801, MC044-L82/M802, MC044-L82/M803, MC044-L82/M804, MC044-L82/M805, MC044-L82/M806, MC044-L82/M807, MC044-L82/M808, MC044-L82/M809, MC044-L82/M810, MC044-L82/M811, MC044-L82/M812, MC044-L82/M813, MC044-L82/M814, MC044-L82/M815, MC044-L82/M816, MC044-L82/M817, MC044-L82/M818, MC044-L82/M819, MC044-L82/M820, MC044-L82/M821, MC044-L82/M822, MC044-L82/M823, MC044-L82/M824, MC044-L82/M825, MC044-L82/M826, MC044-L82/M827, MC044-L82/M828, MC044-L82/M829, MC044-L82/M830, MC044-L82/M831, MC044-L82/M832, MC044-L82/M833, MC044-L82/M834, MC044-L82/M835, MC044-L82/M836, MC044-L82/M837, MC044-L82/M838, MC044-L82/M839, MC044-L82/M840, MC044-L82/M841, MC044-L82/M842, MC044-L82/M843, MC044-L82/M844, MC045-L82/M775, MC045-L82/M776, MC045-L82/M777, MC045-L82/M778, MC045-L82/M779, MC045-L82/M780, MC045-L82/M781, MC045-L82/M782, MC045-L82/M783, MC045-L82/M784, MC045-L82/M785, MC045-L82/M786, MC045-L82/M787, MC045-L82/M788, MC045-L82/M789, MC045-L82/M790, MC045-L82/M791, MC045-L82/M792, MC045-L82/M793, MC045-L82/M947, MC045-L82/M948, MC045-L82/M949, MC045-L82/M950, MC045-L82/M951, MC045-L82/M952, MC046-L82/M736, MC046-L82/M737, MC046-L82/M738, MC046-L82/M739, MC046-L82/M740, MC046-L82/M741, MC046-L82/M742, MC046-L82/M743, MC046-L82/M744, MC047-L02/M888, MC061-L99/M305, MC061-L99/M310, MC063-L82/M955, MC065-L82/M900, MC065-L82/M901, MC065-L82/M902, MC065-L82/M903, MC065-L82/M904, MC065-L82/M905, MC065-L82/M906, MC065-L82/M907, MC065-L82/M908, MC065-L82/M909, MC065-L82/M910, MC065-L82/M911, MC065-L82/M912, MC065-L82/M913, MC065-L82/M914, MC065-L82/M915, MC065-L82/M935, MC065-L82/M936, MC065-L82/M937, MC070-L82/M932, MC070-L82/M933, MC070-L82/M934, MC070-L82/M960, MC070-L82/M961, MC070-L82/M962, MC070-L82/M963, MC070-L82/M964, MC070-L82/M965, MC070-L82/M966, MC070-L82/M967, MC070-L82/M968, MC070-L82/M969, MC070-L82/M970, MC070-L82/M971, MC071-L82/M917, MC071-L82/M918, MC071-L82/M919, MC071-L82/M920, MC071-L82/M921, MC072-L82/M928, MC075-L82/M942, MC075-L82/M943, MC075-L82/M944, MC075-L82/M945, MC075-L82/M946, MC102-L82/M700, MC102-L82/M701, MC102-L82/M702, MC102-L82/M703, MC102-L82/M704, MC102-L82/M705, MC102-L82/M706, MC102-L82/M707, MC102-L82/M708, MC102-L82/M709, MC102-L82/M710, MC102-L82/M711, MC102-L82/M712, MC102-L82/M713, MC102-L82/M714, MC102-L82/M715, MC102-L82/M716, MC102-L82/M717, MC102-L82/M718, MC102-L82/M719, MC102-L82/M866, MC102-L82/M867, MC102-L82/M868, MC102-L82/M869, MC102-L82/M870, MC102-L82/M871, MC102-L82/M872, MC102-L82/M873, MC102-L82/M874, MC102-L82/M875, MC102-L82/M876, MC102-L82/M877, MC102-L82/M878, MC102-L82/M879, MC102-L82/M880, MC102-L82/M881, MC102-L82/M882, MC102-L82/M883, MC102-L82/M884, MC102-L82/M885, MC102-L82/M886, MC102-L82/M887, MC102-L99/M309, MC103-L99/M216, MC103-L99/M300, MC103-L99/M504, MC125-L82/M929, MC126-L82/M930, MC126-L82/M931, MC128-L82/M926, MC128-L82/M927, MC129-L82/M922, MC129-L82/M923, MC131-L82/M924, MC131-L82/M925, MC197-L82/M888, MC197-L82/M889, MC197-L82/M890, MC197-L82/M891, MC197-L82/M892, MC197-L82/M893, MC197-L82/M894, MC197-L82/M895, MC197-L82/M896, MC197-L82/M897, MC200-L82/M938, MC200-L82/M939, MC200-L82/M940, MC200-L82/M941, MC204-L82/M956, MC204-L82/M957, MC204-L82/M958, MC204-L82/M959, MC204-L99/M312, MC207-L82/M845, MC207-L82/M846, MC207-L82/M847, MC207-L82/M848, MC207-L82/M849, MC207-L82/M850, MC207-L82/M851, MC207-L82/M852, MC207-L82/M853, MC207-L82/M854, MC207-L82/M855, MC207-L82/M856, MC207-L82/M857, MC210-L01/M001, MC210-L01/M002, MC210-L01/M003, MC210-L01/M004, MC210-L01/M005, MC210-L01/M006, MC210-L01/M007, MC210-L01/M008, MC210-L01/M009, MC210-L01/M010, MC210-L01/M011, MC210-L01/M012, MC210-L01/M013, MC210-L01/M014, MC210-L01/M015, MC210-L01/M016, MC210-L01/M017, MC210-L01/M018, MC210-L01/M019, MC210-L01/M020, MC210-L01/M021, MC210-L01/M022, MC210-L01/M023, MC210-L01/M024, MC210-L01/M025, MC210-L01/M026, MC210-L01/M027, MC210-L01/M028, MC210-L01/M029, MC210-L01/M030, MC210-L02/M001, MC210-L02/M002, MC210-L02/M003, MC210-L02/M004, MC210-L02/M005, MC210-L02/M006, MC210-L02/M007, MC210-L02/M008, MC210-L02/M009, MC210-L02/M010, MC210-L02/M011, MC210-L02/M012, MC210-L02/M013, MC210-L02/M014, MC210-L02/M015, MC210-L02/M016, MC210-L02/M017, MC210-L02/M018, MC210-L02/M019, MC210-L02/M020, MC210-L02/M021, MC210-L02/M022, MC210-L02/M023, MC210-L82/M720, MC210-L82/M721, MC210-L82/M722, MC210-L82/M723, MC210-L82/M724, MC210-L82/M725, MC210-L82/M726, MC210-L82/M727, MC210-L82/M728, MC210-L82/M729, MC210-L82/M730, MC210-L82/M731, MC210-L82/M732, MC210-L82/M733, MC210-L82/M734, MC210-L82/M735, MC211-L82/M858, MC211-L82/M859, MC211-L82/M860, MC211-L82/M861, MC211-L82/M862, MC211-L82/M863, MC211-L82/M864, MC211-L82/M865, OC004-L99/M206, OC004-L99/M512, OC005-L99/M204, OC005-L99/M505, OC006-L99/M200, OC006-L99/M503, 

Meters in Master, but not in Planon: 364 / 29188 : 1.247 %

In [604]:
q1=pd.DataFrame(meterssensors_not_in_planon)

In [605]:
a=np.sort(list(set(planon_meterssensors_filtered.index)))
b=np.sort(list(set(master_meterssensors_for_validation_filtered.index)))
meterssensors_not_in_master=[]
for i in a:
    if i not in b:
        print(i+',',end=" "),
        meterssensors_not_in_master.append(i)
print('\n\nMeters in Planon, not in Master:',
      len(meterssensors_not_in_master),'/',len(a),':',
      round(len(meterssensors_not_in_master)/len(a)*100,3),'%')



Meters in Planon, not in Master: 0 / 28824 : 0.0 %

In [606]:
q2=pd.DataFrame(meterssensors_not_in_master)

In [607]:
a=np.sort(list(set(planon_loggerscontrollers_filtered.index)))
b=np.sort(list(set(master_loggerscontrollers_for_validation_filtered.index)))
loggerscontrollers_not_in_planon=[]
for i in b:
    if i not in a:
        print(i+',',end=" "),
        loggerscontrollers_not_in_planon.append(i)
print('\n\nLoggers in Master, but not in Planon:',
      len(loggerscontrollers_not_in_planon),'/',len(b),':',
      round(len(loggerscontrollers_not_in_planon)/len(b)*100,3),'%')


MC032-L01, MC032-L03, MC044-L02, MC044-L03, MC044-L04, MC044-L05, MC046-L01, MC046-L03, MC046-L04, MC061-L01, MC076-B03, MC202-B17, MC202-L04, MC204-L03, MC204-L04, MC204-L07, MC204-L08, MC204-L09, MC207-L01, 

Loggers in Master, but not in Planon: 19 / 378 : 5.026 %

In [608]:
q3=pd.DataFrame(loggerscontrollers_not_in_planon)

In [609]:
a=np.sort(list(set(planon_loggerscontrollers_filtered.index)))
b=np.sort(list(set(master_loggerscontrollers_for_validation_filtered.index)))
loggerscontrollers_not_in_master=[]
for i in a:
    if i not in b:
        print(i+',',end=" "),
        loggerscontrollers_not_in_master.append(i)
print('\n\nLoggers in Planon, not in Master:',
      len(loggerscontrollers_not_in_master),'/',len(a),':',
      round(len(loggerscontrollers_not_in_master)/len(a)*100,3),'%')



Loggers in Planon, not in Master: 0 / 359 : 0.0 %

In [610]:
q4=pd.DataFrame(loggerscontrollers_not_in_master)

In [611]:
q5=pd.DataFrame((planon_meterssensors_intersected!=master_meterssensors_for_validation_intersected).sum()/\
len(planon_meterssensors_intersected)*100)

In [612]:
q6=pd.DataFrame((planon_loggerscontrollers_intersected!=master_loggerscontrollers_for_validation_intersected).sum()/\
len(planon_loggerscontrollers_intersected)*100)

In [613]:
w1=[]
for i in planon_meterssensors_intersected[planon_meterssensors_intersected['Description']!=master_meterssensors_for_validation_intersected['Description']].index:
    w1.append({"Meter":i,'Planon':planon_meterssensors_intersected.loc[i]['Description'],
               'Master':master_meterssensors_for_validation_intersected.loc[i]['Description']})

In [614]:
q7=pd.DataFrame(w1)

In [615]:
w2=[]
for i in planon_loggerscontrollers_intersected[planon_loggerscontrollers_intersected['Building Name']!=master_loggerscontrollers_for_validation_intersected['Building Name']].index:
    w2.append({"Logger":i,'Planon':planon_loggerscontrollers_intersected.loc[i]['Building Name'],
               'Master':master_loggerscontrollers_for_validation_intersected.loc[i]['Building Name']})

In [616]:
q8=pd.DataFrame(w2)

In [617]:
writer = pd.ExcelWriter('final5b.xlsx')
q1.to_excel(writer,'Meters Master, not Planon')
q2.to_excel(writer,'Meters Planon, not Master')
q3.to_excel(writer,'Loggers Master, not Planon')
q4.to_excel(writer,'Loggers Planon, not Master')
q5.to_excel(writer,'Meters error perc')
q6.to_excel(writer,'Loggers error perc')
q7.to_excel(writer,'Meters naming conflcits')

In [618]:
q1


Out[618]:
0
0 AP000-L99/M303
1 AP000-L99/M308
2 AP080-L79/M001
3 AP080-L80/M001
4 AP080-L81/M001
5 MC000-L99/M201
6 MC000-L99/M202
7 MC000-L99/M203
8 MC000-L99/M506
9 MC001-L82/M972
10 MC001-L82/M973
11 MC001-L82/M974
12 MC001-L82/M975
13 MC001-L82/M976
14 MC001-L99/M100
15 MC001-L99/M222
16 MC001-L99/M224
17 MC001-L99/M306
18 MC001-L99/M508
19 MC003-L99/M207
20 MC003-L99/M304
21 MC003-L99/M509
22 MC007-L99/M211
23 MC007-L99/M511
24 MC008-L82/M916
25 MC008-L99/M302
26 MC010-L82/M745
27 MC010-L82/M746
28 MC010-L82/M747
29 MC010-L82/M748
... ...
334 MC210-L82/M720
335 MC210-L82/M721
336 MC210-L82/M722
337 MC210-L82/M723
338 MC210-L82/M724
339 MC210-L82/M725
340 MC210-L82/M726
341 MC210-L82/M727
342 MC210-L82/M728
343 MC210-L82/M729
344 MC210-L82/M730
345 MC210-L82/M731
346 MC210-L82/M732
347 MC210-L82/M733
348 MC210-L82/M734
349 MC210-L82/M735
350 MC211-L82/M858
351 MC211-L82/M859
352 MC211-L82/M860
353 MC211-L82/M861
354 MC211-L82/M862
355 MC211-L82/M863
356 MC211-L82/M864
357 MC211-L82/M865
358 OC004-L99/M206
359 OC004-L99/M512
360 OC005-L99/M204
361 OC005-L99/M505
362 OC006-L99/M200
363 OC006-L99/M503

364 rows × 1 columns


In [619]:
q9=[]
try:
    for i in q1[0].values:
        if i[:i.find('/')] not in set(q3[0].values):
            q9.append(i)
except:pass

In [620]:
pd.DataFrame(q9).to_excel(writer,'Meters Master, not Planon, not Logger')
writer.save()


C:\Anaconda2\envs\python3\lib\site-packages\openpyxl\workbook\child.py:99: UserWarning: Title is more than 31 characters. Some applications may not be able to read the file
  warnings.warn("Title is more than 31 characters. Some applications may not be able to read the file")

In [ ]: