mirror of
https://github.com/DOI-DO/j40-cejst-2.git
synced 2025-07-28 13:41:17 -07:00
Adding first street foundation data (#1823)
Adding FSF flood and wildfire risk datasets to the score.
This commit is contained in:
parent
ebac552d75
commit
5e378aea81
21 changed files with 430 additions and 82 deletions
|
@ -272,3 +272,21 @@ fields:
|
||||||
- score_name: Leaky underground storage tanks
|
- score_name: Leaky underground storage tanks
|
||||||
label: Leaky underground storage tanks
|
label: Leaky underground storage tanks
|
||||||
format: float
|
format: float
|
||||||
|
- score_name: Share of properties at risk of flood in 30 years
|
||||||
|
label: Share of properties at risk of flood in 30 years
|
||||||
|
format: float
|
||||||
|
- score_name: Share of properties at risk of fire in 30 years
|
||||||
|
label: Share of properties at risk of fire in 30 years
|
||||||
|
format: float
|
||||||
|
- score_name: Greater than or equal to the 90th percentile for share of properties at risk of flood in 30 years and is low income?
|
||||||
|
label: Greater than or equal to the 90th percentile for share of properties at risk of flood in 30 years and is low income?
|
||||||
|
format: bool
|
||||||
|
- score_name: Greater than or equal to the 90th percentile for share of properties at risk of fire in 30 years and is low income?
|
||||||
|
label: Greater than or equal to the 90th percentile for share of properties at risk of fire in 30 years and is low income?
|
||||||
|
format: bool
|
||||||
|
- score_name: Greater than or equal to the 90th percentile for share of properties at risk of flood in 30 years
|
||||||
|
label: Greater than or equal to the 90th percentile for share of properties at risk of flood in 30 years
|
||||||
|
format: bool
|
||||||
|
- score_name: Greater than or equal to the 90th percentile for share of properties at risk of fire in 30 years
|
||||||
|
label: Greater than or equal to the 90th percentile for share of properties at risk of fire in 30 years
|
||||||
|
format: bool
|
|
@ -276,3 +276,21 @@ sheets:
|
||||||
- score_name: Greater than or equal to the 90th percentile for low median household income as a percent of area median income and has low HS education in 2009 (island areas)?
|
- score_name: Greater than or equal to the 90th percentile for low median household income as a percent of area median income and has low HS education in 2009 (island areas)?
|
||||||
label: Greater than or equal to the 90th percentile for low median household income as a percent of area median income and has low HS education in 2009 (island areas)?
|
label: Greater than or equal to the 90th percentile for low median household income as a percent of area median income and has low HS education in 2009 (island areas)?
|
||||||
format: bool
|
format: bool
|
||||||
|
- score_name: Share of properties at risk of flood in 30 years
|
||||||
|
label: Share of properties at risk of flood in 30 years
|
||||||
|
format: float
|
||||||
|
- score_name: Share of properties at risk of fire in 30 years
|
||||||
|
label: Share of properties at risk of fire in 30 years
|
||||||
|
format: float
|
||||||
|
- score_name: Greater than or equal to the 90th percentile for share of properties at risk of flood in 30 years and is low income?
|
||||||
|
label: Greater than or equal to the 90th percentile for share of properties at risk of flood in 30 years and is low income?
|
||||||
|
format: bool
|
||||||
|
- score_name: Greater than or equal to the 90th percentile for share of properties at risk of fire in 30 years and is low income?
|
||||||
|
label: Greater than or equal to the 90th percentile for share of properties at risk of fire in 30 years and is low income?
|
||||||
|
format: bool
|
||||||
|
- score_name: Greater than or equal to the 90th percentile for share of properties at risk of flood in 30 years
|
||||||
|
label: Greater than or equal to the 90th percentile for share of properties at risk of flood in 30 years
|
||||||
|
format: bool
|
||||||
|
- score_name: Greater than or equal to the 90th percentile for share of properties at risk of fire in 30 years
|
||||||
|
label: Greater than or equal to the 90th percentile for share of properties at risk of fire in 30 years
|
||||||
|
format: bool
|
||||||
|
|
|
@ -34,6 +34,16 @@ DATASET_LIST = [
|
||||||
"module_dir": "mapping_for_ej",
|
"module_dir": "mapping_for_ej",
|
||||||
"class_name": "MappingForEJETL",
|
"class_name": "MappingForEJETL",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "fsf_flood_risk",
|
||||||
|
"module_dir": "fsf_flood_risk",
|
||||||
|
"class_name": "FloodRiskETL",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fsf_wildfire_risk",
|
||||||
|
"module_dir": "fsf_wildfire_risk",
|
||||||
|
"class_name": "WildfireRiskETL",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "ejscreen",
|
"name": "ejscreen",
|
||||||
"module_dir": "ejscreen",
|
"module_dir": "ejscreen",
|
||||||
|
|
|
@ -157,6 +157,88 @@ datasets:
|
||||||
include_in_tiles: true
|
include_in_tiles: true
|
||||||
include_in_downloadable_files: true
|
include_in_downloadable_files: true
|
||||||
|
|
||||||
|
- long_name: "First Street Foundation Flood Risk"
|
||||||
|
short_name: "FSF Flood Risk"
|
||||||
|
module_name: fsf_flood_risk
|
||||||
|
input_geoid_tract_field_name: "GEOID"
|
||||||
|
load_fields:
|
||||||
|
- short_name: "flood_eligible_properties"
|
||||||
|
df_field_name: "COUNT_PROPERTIES"
|
||||||
|
long_name: "Count of properties eligible for flood risk calculation within tract (floor of 250)"
|
||||||
|
field_type: float
|
||||||
|
include_in_tiles: false
|
||||||
|
include_in_downloadable_files: true
|
||||||
|
create_percentile: false
|
||||||
|
- short_name: "flood_risk_properties_today"
|
||||||
|
df_field_name: "PROPERTIES_AT_RISK_FROM_FLOODING_TODAY"
|
||||||
|
long_name: "Count of properties at risk of flood today"
|
||||||
|
field_type: float
|
||||||
|
include_in_tiles: false
|
||||||
|
include_in_downloadable_files: true
|
||||||
|
create_percentile: false
|
||||||
|
- short_name: "flood_risk_properties_30yrs"
|
||||||
|
df_field_name: "PROPERTIES_AT_RISK_FROM_FLOODING_IN_30_YEARS"
|
||||||
|
long_name: "Count of properties at risk of flood in 30 years"
|
||||||
|
field_type: float
|
||||||
|
include_in_tiles: false
|
||||||
|
include_in_downloadable_files: true
|
||||||
|
create_percentile: false
|
||||||
|
- short_name: "flood_risk_share_today"
|
||||||
|
df_field_name: "SHARE_OF_PROPERTIES_AT_RISK_FROM_FLOODING_TODAY"
|
||||||
|
long_name: "Share of properties at risk of flood today"
|
||||||
|
field_type: float
|
||||||
|
include_in_tiles: false
|
||||||
|
include_in_downloadable_files: true
|
||||||
|
create_percentile: true
|
||||||
|
- short_name: "flood_risk_share_30yrs"
|
||||||
|
df_field_name: "SHARE_OF_PROPERTIES_AT_RISK_FROM_FLOODING_IN_30_YEARS"
|
||||||
|
long_name: "Share of properties at risk of flood in 30 years"
|
||||||
|
field_type: float
|
||||||
|
include_in_tiles: false
|
||||||
|
include_in_downloadable_files: true
|
||||||
|
create_percentile: true
|
||||||
|
|
||||||
|
- long_name: "First Street Foundation Wildfire Risk"
|
||||||
|
short_name: "FSF Wildfire Risk"
|
||||||
|
module_name: fsf_wildfire_risk
|
||||||
|
input_geoid_tract_field_name: "GEOID"
|
||||||
|
load_fields:
|
||||||
|
- short_name: "fire_eligible_properties"
|
||||||
|
df_field_name: "COUNT_PROPERTIES"
|
||||||
|
long_name: "Count of properties eligible for wildfire risk calculation within tract (floor of 250)"
|
||||||
|
field_type: float
|
||||||
|
include_in_tiles: false
|
||||||
|
include_in_downloadable_files: true
|
||||||
|
create_percentile: false
|
||||||
|
- short_name: "fire_risk_properties_today"
|
||||||
|
df_field_name: "PROPERTIES_AT_RISK_FROM_FIRE_TODAY"
|
||||||
|
long_name: "Count of properties at risk of wildfire today"
|
||||||
|
field_type: float
|
||||||
|
include_in_tiles: false
|
||||||
|
include_in_downloadable_files: true
|
||||||
|
create_percentile: false
|
||||||
|
- short_name: "fire_risk_properties_30yrs"
|
||||||
|
df_field_name: "PROPERTIES_AT_RISK_FROM_FIRE_IN_30_YEARS"
|
||||||
|
long_name: "Count of properties at risk of wildfire in 30 years"
|
||||||
|
field_type: float
|
||||||
|
include_in_tiles: false
|
||||||
|
include_in_downloadable_files: true
|
||||||
|
create_percentile: false
|
||||||
|
- short_name: "fire_risk_share_today"
|
||||||
|
df_field_name: "SHARE_OF_PROPERTIES_AT_RISK_FROM_FIRE_TODAY"
|
||||||
|
long_name: "Share of properties at risk of fire today"
|
||||||
|
field_type: float
|
||||||
|
include_in_tiles: false
|
||||||
|
include_in_downloadable_files: true
|
||||||
|
create_percentile: true
|
||||||
|
- short_name: "fire_risk_share_30yrs"
|
||||||
|
df_field_name: "SHARE_OF_PROPERTIES_AT_RISK_FROM_FIRE_IN_30_YEARS"
|
||||||
|
long_name: "Share of properties at risk of fire in 30 years"
|
||||||
|
field_type: float
|
||||||
|
include_in_tiles: false
|
||||||
|
include_in_downloadable_files: true
|
||||||
|
create_percentile: true
|
||||||
|
|
||||||
- long_name: "DOT Travel Disadvantage Index"
|
- long_name: "DOT Travel Disadvantage Index"
|
||||||
short_name: "DOT"
|
short_name: "DOT"
|
||||||
module_name: "travel_composite"
|
module_name: "travel_composite"
|
||||||
|
|
|
@ -293,12 +293,18 @@ TILES_SCORE_COLUMNS = {
|
||||||
field_names.WORKFORCE_THRESHOLD_EXCEEDED: "M_WKFC_EOMI",
|
field_names.WORKFORCE_THRESHOLD_EXCEEDED: "M_WKFC_EOMI",
|
||||||
# These are the booleans for socioeconomic indicators
|
# These are the booleans for socioeconomic indicators
|
||||||
## this measures low income boolean
|
## this measures low income boolean
|
||||||
field_names.FPL_200_SERIES: "FPL200S",
|
field_names.FPL_200_SERIES_IMPUTED_AND_ADJUSTED: "FPL200S",
|
||||||
## Low high school for t&wd
|
## Low high school for t&wd
|
||||||
field_names.WORKFORCE_SOCIO_INDICATORS_EXCEEDED: "M_WKFC_EBSI",
|
field_names.WORKFORCE_SOCIO_INDICATORS_EXCEEDED: "M_WKFC_EBSI",
|
||||||
field_names.DOT_BURDEN_PCTILE_THRESHOLD: "TD_ET",
|
field_names.DOT_BURDEN_PCTILE_THRESHOLD: "TD_ET",
|
||||||
field_names.DOT_TRAVEL_BURDEN_FIELD
|
field_names.DOT_TRAVEL_BURDEN_FIELD
|
||||||
+ field_names.PERCENTILE_FIELD_SUFFIX: "TD_PFS"
|
+ field_names.PERCENTILE_FIELD_SUFFIX: "TD_PFS",
|
||||||
|
field_names.FUTURE_FLOOD_RISK_FIELD
|
||||||
|
+ field_names.PERCENTILE_FIELD_SUFFIX: "FLD_PFS",
|
||||||
|
field_names.FUTURE_WILDFIRE_RISK_FIELD
|
||||||
|
+ field_names.PERCENTILE_FIELD_SUFFIX: "WF_PFS",
|
||||||
|
field_names.HIGH_FUTURE_FLOOD_RISK_FIELD: "FLD_ET",
|
||||||
|
field_names.HIGH_FUTURE_WILDFIRE_RISK_FIELD: "WF_ET",
|
||||||
## FPL 200 and low higher ed for all others should no longer be M_EBSI, but rather
|
## FPL 200 and low higher ed for all others should no longer be M_EBSI, but rather
|
||||||
## FPL_200 (there is no higher ed in narwhal)
|
## FPL_200 (there is no higher ed in narwhal)
|
||||||
}
|
}
|
||||||
|
@ -352,4 +358,7 @@ TILES_SCORE_FLOAT_COLUMNS = [
|
||||||
field_names.COLLEGE_NON_ATTENDANCE_FIELD,
|
field_names.COLLEGE_NON_ATTENDANCE_FIELD,
|
||||||
field_names.COLLEGE_ATTENDANCE_FIELD,
|
field_names.COLLEGE_ATTENDANCE_FIELD,
|
||||||
field_names.DOT_TRAVEL_BURDEN_FIELD + field_names.PERCENTILE_FIELD_SUFFIX,
|
field_names.DOT_TRAVEL_BURDEN_FIELD + field_names.PERCENTILE_FIELD_SUFFIX,
|
||||||
|
field_names.FUTURE_FLOOD_RISK_FIELD + field_names.PERCENTILE_FIELD_SUFFIX,
|
||||||
|
field_names.FUTURE_WILDFIRE_RISK_FIELD
|
||||||
|
+ field_names.PERCENTILE_FIELD_SUFFIX,
|
||||||
]
|
]
|
||||||
|
|
|
@ -11,6 +11,10 @@ from data_pipeline.etl.sources.national_risk_index.etl import (
|
||||||
from data_pipeline.etl.sources.dot_travel_composite.etl import (
|
from data_pipeline.etl.sources.dot_travel_composite.etl import (
|
||||||
TravelCompositeETL,
|
TravelCompositeETL,
|
||||||
)
|
)
|
||||||
|
from data_pipeline.etl.sources.fsf_flood_risk.etl import (
|
||||||
|
FloodRiskETL,
|
||||||
|
)
|
||||||
|
from data_pipeline.etl.sources.fsf_wildfire_risk.etl import WildfireRiskETL
|
||||||
from data_pipeline.score.score_runner import ScoreRunner
|
from data_pipeline.score.score_runner import ScoreRunner
|
||||||
from data_pipeline.score import field_names
|
from data_pipeline.score import field_names
|
||||||
from data_pipeline.etl.score import constants
|
from data_pipeline.etl.score import constants
|
||||||
|
@ -41,6 +45,8 @@ class ScoreETL(ExtractTransformLoad):
|
||||||
self.child_opportunity_index_df: pd.DataFrame
|
self.child_opportunity_index_df: pd.DataFrame
|
||||||
self.hrs_df: pd.DataFrame
|
self.hrs_df: pd.DataFrame
|
||||||
self.dot_travel_disadvantage_df: pd.DataFrame
|
self.dot_travel_disadvantage_df: pd.DataFrame
|
||||||
|
self.fsf_flood_df: pd.DataFrame
|
||||||
|
self.fsf_fire_df: pd.DataFrame
|
||||||
|
|
||||||
def extract(self) -> None:
|
def extract(self) -> None:
|
||||||
logger.info("Loading data sets from disk.")
|
logger.info("Loading data sets from disk.")
|
||||||
|
@ -122,6 +128,12 @@ class ScoreETL(ExtractTransformLoad):
|
||||||
# Load DOT Travel Disadvantage
|
# Load DOT Travel Disadvantage
|
||||||
self.dot_travel_disadvantage_df = TravelCompositeETL.get_data_frame()
|
self.dot_travel_disadvantage_df = TravelCompositeETL.get_data_frame()
|
||||||
|
|
||||||
|
# Load fire risk data
|
||||||
|
self.fsf_fire_df = WildfireRiskETL.get_data_frame()
|
||||||
|
|
||||||
|
# Load flood risk data
|
||||||
|
self.fsf_flood_df = FloodRiskETL.get_data_frame()
|
||||||
|
|
||||||
# Load GeoCorr Urban Rural Map
|
# Load GeoCorr Urban Rural Map
|
||||||
geocorr_urban_rural_csv = (
|
geocorr_urban_rural_csv = (
|
||||||
constants.DATA_PATH / "dataset" / "geocorr" / "usa.csv"
|
constants.DATA_PATH / "dataset" / "geocorr" / "usa.csv"
|
||||||
|
@ -342,6 +354,8 @@ class ScoreETL(ExtractTransformLoad):
|
||||||
self.child_opportunity_index_df,
|
self.child_opportunity_index_df,
|
||||||
self.hrs_df,
|
self.hrs_df,
|
||||||
self.dot_travel_disadvantage_df,
|
self.dot_travel_disadvantage_df,
|
||||||
|
self.fsf_flood_df,
|
||||||
|
self.fsf_fire_df,
|
||||||
]
|
]
|
||||||
|
|
||||||
# Sanity check each data frame before merging.
|
# Sanity check each data frame before merging.
|
||||||
|
@ -426,6 +440,8 @@ class ScoreETL(ExtractTransformLoad):
|
||||||
field_names.UST_FIELD,
|
field_names.UST_FIELD,
|
||||||
field_names.DOT_TRAVEL_BURDEN_FIELD,
|
field_names.DOT_TRAVEL_BURDEN_FIELD,
|
||||||
field_names.AGRICULTURAL_VALUE_BOOL_FIELD,
|
field_names.AGRICULTURAL_VALUE_BOOL_FIELD,
|
||||||
|
field_names.FUTURE_FLOOD_RISK_FIELD,
|
||||||
|
field_names.FUTURE_WILDFIRE_RISK_FIELD,
|
||||||
field_names.POVERTY_LESS_THAN_200_FPL_IMPUTED_FIELD,
|
field_names.POVERTY_LESS_THAN_200_FPL_IMPUTED_FIELD,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,3 @@
|
||||||
|
# FSF flood risk data
|
||||||
|
|
||||||
|
Flood risk computed as 1 in 100 year flood zone
|
|
@ -0,0 +1,93 @@
|
||||||
|
# pylint: disable=unsubscriptable-object
|
||||||
|
# pylint: disable=unsupported-assignment-operation
|
||||||
|
|
||||||
|
import pandas as pd
|
||||||
|
from data_pipeline.config import settings
|
||||||
|
|
||||||
|
from data_pipeline.etl.base import ExtractTransformLoad, ValidGeoLevel
|
||||||
|
from data_pipeline.utils import get_module_logger
|
||||||
|
|
||||||
|
logger = get_module_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class FloodRiskETL(ExtractTransformLoad):
|
||||||
|
"""ETL class for the First Street Foundation flood risk dataset"""
|
||||||
|
|
||||||
|
NAME = "fsf_flood_risk"
|
||||||
|
SOURCE_URL = settings.AWS_JUSTICE40_DATASOURCES_URL + "/fsf_flood.zip"
|
||||||
|
GEO_LEVEL = ValidGeoLevel.CENSUS_TRACT
|
||||||
|
|
||||||
|
# Output score variables (values set on datasets.yml) for linting purposes
|
||||||
|
COUNT_PROPERTIES: str
|
||||||
|
PROPERTIES_AT_RISK_FROM_FLOODING_TODAY: str
|
||||||
|
PROPERTIES_AT_RISK_FROM_FLOODING_IN_30_YEARS: str
|
||||||
|
SHARE_OF_PROPERTIES_AT_RISK_FROM_FLOODING_TODAY: str
|
||||||
|
SHARE_OF_PROPERTIES_AT_RISK_FROM_FLOODING_IN_30_YEARS: str
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
# define the full path for the input CSV file
|
||||||
|
self.INPUT_CSV = (
|
||||||
|
self.get_tmp_path() / "fsf_flood" / "flood_tract_2010.csv"
|
||||||
|
)
|
||||||
|
|
||||||
|
# this is the main dataframe
|
||||||
|
self.df: pd.DataFrame
|
||||||
|
|
||||||
|
# Start dataset-specific vars here
|
||||||
|
self.COUNT_PROPERTIES_NATIVE_FIELD_NAME = "count_properties"
|
||||||
|
self.COUNT_PROPERTIES_AT_RISK_TODAY = "mid_depth_100_year00"
|
||||||
|
self.COUNT_PROPERTIES_AT_RISK_30_YEARS = "mid_depth_100_year30"
|
||||||
|
self.CLIP_PROPERTIES_COUNT = 250
|
||||||
|
|
||||||
|
def transform(self) -> None:
|
||||||
|
"""Reads the unzipped data file into memory and applies the following
|
||||||
|
transformations to prepare it for the load() method:
|
||||||
|
|
||||||
|
- Renames the Census Tract column to match the other datasets
|
||||||
|
- Calculates share of properties at risk, left-clipping number of properties at 250
|
||||||
|
"""
|
||||||
|
logger.info("Transforming National Risk Index Data")
|
||||||
|
|
||||||
|
logger.info(self.COLUMNS_TO_KEEP)
|
||||||
|
# read in the unzipped csv data source then rename the
|
||||||
|
# Census Tract column for merging
|
||||||
|
df_fsf_flood_disagg: pd.DataFrame = pd.read_csv(
|
||||||
|
self.INPUT_CSV,
|
||||||
|
dtype={self.INPUT_GEOID_TRACT_FIELD_NAME: str},
|
||||||
|
low_memory=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
df_fsf_flood_disagg[self.GEOID_TRACT_FIELD_NAME] = df_fsf_flood_disagg[
|
||||||
|
self.INPUT_GEOID_TRACT_FIELD_NAME
|
||||||
|
].str.zfill(11)
|
||||||
|
|
||||||
|
# Because we have some tracts that are listed twice, we aggregate based on
|
||||||
|
# GEOID10_TRACT. Note that I haven't confirmed this with the FSF boys -- to do!
|
||||||
|
df_fsf_flood = (
|
||||||
|
df_fsf_flood_disagg.groupby(self.GEOID_TRACT_FIELD_NAME)
|
||||||
|
.sum()
|
||||||
|
.reset_index()
|
||||||
|
)
|
||||||
|
|
||||||
|
df_fsf_flood[self.COUNT_PROPERTIES] = df_fsf_flood[
|
||||||
|
self.COUNT_PROPERTIES_NATIVE_FIELD_NAME
|
||||||
|
].clip(lower=self.CLIP_PROPERTIES_COUNT)
|
||||||
|
|
||||||
|
df_fsf_flood[self.SHARE_OF_PROPERTIES_AT_RISK_FROM_FLOODING_TODAY] = (
|
||||||
|
df_fsf_flood[self.COUNT_PROPERTIES_AT_RISK_TODAY]
|
||||||
|
/ df_fsf_flood[self.COUNT_PROPERTIES]
|
||||||
|
)
|
||||||
|
df_fsf_flood[
|
||||||
|
self.SHARE_OF_PROPERTIES_AT_RISK_FROM_FLOODING_IN_30_YEARS
|
||||||
|
] = (
|
||||||
|
df_fsf_flood[self.COUNT_PROPERTIES_AT_RISK_30_YEARS]
|
||||||
|
/ df_fsf_flood[self.COUNT_PROPERTIES]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Assign the final df to the class' output_df for the load method with rename
|
||||||
|
self.output_df = df_fsf_flood.rename(
|
||||||
|
columns={
|
||||||
|
self.COUNT_PROPERTIES_AT_RISK_TODAY: self.PROPERTIES_AT_RISK_FROM_FLOODING_TODAY,
|
||||||
|
self.COUNT_PROPERTIES_AT_RISK_30_YEARS: self.PROPERTIES_AT_RISK_FROM_FLOODING_IN_30_YEARS,
|
||||||
|
}
|
||||||
|
)
|
|
@ -0,0 +1,3 @@
|
||||||
|
# FSF wildfire risk data
|
||||||
|
|
||||||
|
Fire risk computed as >= 0.003 burn risk probability
|
|
@ -0,0 +1,91 @@
|
||||||
|
# pylint: disable=unsubscriptable-object
|
||||||
|
# pylint: disable=unsupported-assignment-operation
|
||||||
|
|
||||||
|
import pandas as pd
|
||||||
|
from data_pipeline.config import settings
|
||||||
|
|
||||||
|
from data_pipeline.etl.base import ExtractTransformLoad, ValidGeoLevel
|
||||||
|
from data_pipeline.utils import get_module_logger
|
||||||
|
|
||||||
|
logger = get_module_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class WildfireRiskETL(ExtractTransformLoad):
|
||||||
|
"""ETL class for the First Street Foundation wildfire risk dataset"""
|
||||||
|
|
||||||
|
NAME = "fsf_wildfire_risk"
|
||||||
|
SOURCE_URL = settings.AWS_JUSTICE40_DATASOURCES_URL + "/fsf_fire.zip"
|
||||||
|
GEO_LEVEL = ValidGeoLevel.CENSUS_TRACT
|
||||||
|
|
||||||
|
# Output score variables (values set on datasets.yml) for linting purposes
|
||||||
|
COUNT_PROPERTIES: str
|
||||||
|
PROPERTIES_AT_RISK_FROM_FIRE_TODAY: str
|
||||||
|
PROPERTIES_AT_RISK_FROM_FIRE_IN_30_YEARS: str
|
||||||
|
SHARE_OF_PROPERTIES_AT_RISK_FROM_FIRE_TODAY: str
|
||||||
|
SHARE_OF_PROPERTIES_AT_RISK_FROM_FIRE_IN_30_YEARS: str
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
# define the full path for the input CSV file
|
||||||
|
self.INPUT_CSV = (
|
||||||
|
self.get_tmp_path() / "fsf_fire" / "fire_tract_2010.csv"
|
||||||
|
)
|
||||||
|
|
||||||
|
# this is the main dataframe
|
||||||
|
self.df: pd.DataFrame
|
||||||
|
|
||||||
|
# Start dataset-specific vars here
|
||||||
|
self.COUNT_PROPERTIES_NATIVE_FIELD_NAME = "count_properties"
|
||||||
|
self.COUNT_PROPERTIES_AT_RISK_TODAY = "burnprob_year00_flag"
|
||||||
|
self.COUNT_PROPERTIES_AT_RISK_30_YEARS = "burnprob_year30_flag"
|
||||||
|
self.CLIP_PROPERTIES_COUNT = 250
|
||||||
|
|
||||||
|
def transform(self) -> None:
|
||||||
|
"""Reads the unzipped data file into memory and applies the following
|
||||||
|
transformations to prepare it for the load() method:
|
||||||
|
|
||||||
|
- Renames the Census Tract column to match the other datasets
|
||||||
|
- Calculates share of properties at risk, left-clipping number of properties at 250
|
||||||
|
"""
|
||||||
|
logger.info("Transforming National Risk Index Data")
|
||||||
|
|
||||||
|
logger.info(self.COLUMNS_TO_KEEP)
|
||||||
|
# read in the unzipped csv data source then rename the
|
||||||
|
# Census Tract column for merging
|
||||||
|
df_fsf_fire_disagg: pd.DataFrame = pd.read_csv(
|
||||||
|
self.INPUT_CSV,
|
||||||
|
dtype={self.INPUT_GEOID_TRACT_FIELD_NAME: str},
|
||||||
|
low_memory=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
df_fsf_fire_disagg[self.GEOID_TRACT_FIELD_NAME] = df_fsf_fire_disagg[
|
||||||
|
self.INPUT_GEOID_TRACT_FIELD_NAME
|
||||||
|
].str.zfill(11)
|
||||||
|
|
||||||
|
# Because we have some tracts that are listed twice, we aggregate based on
|
||||||
|
# GEOID10_TRACT. Note that I haven't confirmed this with the FSF boys -- to do!
|
||||||
|
df_fsf_fire = (
|
||||||
|
df_fsf_fire_disagg.groupby(self.GEOID_TRACT_FIELD_NAME)
|
||||||
|
.sum()
|
||||||
|
.reset_index()
|
||||||
|
)
|
||||||
|
|
||||||
|
df_fsf_fire[self.COUNT_PROPERTIES] = df_fsf_fire[
|
||||||
|
self.COUNT_PROPERTIES_NATIVE_FIELD_NAME
|
||||||
|
].clip(lower=self.CLIP_PROPERTIES_COUNT)
|
||||||
|
|
||||||
|
df_fsf_fire[self.SHARE_OF_PROPERTIES_AT_RISK_FROM_FIRE_TODAY] = (
|
||||||
|
df_fsf_fire[self.COUNT_PROPERTIES_AT_RISK_TODAY]
|
||||||
|
/ df_fsf_fire[self.COUNT_PROPERTIES]
|
||||||
|
)
|
||||||
|
df_fsf_fire[self.SHARE_OF_PROPERTIES_AT_RISK_FROM_FIRE_IN_30_YEARS] = (
|
||||||
|
df_fsf_fire[self.COUNT_PROPERTIES_AT_RISK_30_YEARS]
|
||||||
|
/ df_fsf_fire[self.COUNT_PROPERTIES]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Assign the final df to the class' output_df for the load method with rename
|
||||||
|
self.output_df = df_fsf_fire.rename(
|
||||||
|
columns={
|
||||||
|
self.COUNT_PROPERTIES_AT_RISK_TODAY: self.PROPERTIES_AT_RISK_FROM_FIRE_TODAY,
|
||||||
|
self.COUNT_PROPERTIES_AT_RISK_30_YEARS: self.PROPERTIES_AT_RISK_FROM_FIRE_IN_30_YEARS,
|
||||||
|
}
|
||||||
|
)
|
|
@ -0,0 +1,28 @@
|
||||||
|
# How to add variables to a score
|
||||||
|
|
||||||
|
So, there's a variable you want to add to the score! Once you have the data source created in `etl/sources`, what should you do? There are 6 steps across a minimum of 7 files.
|
||||||
|
|
||||||
|
__Updating `field_names.py`__
|
||||||
|
Per indicator, you need to make (usually) three variables to get used in other files.
|
||||||
|
- raw variable: this is the name of the variable's raw data, not scaled into a percentile
|
||||||
|
- variable with threshold exceeded: this is a boolean for whether the tract meets the threshold for the indicator alone
|
||||||
|
- variable with threshold exceeded and socioeconomic criterion exceeded: this is whether the tract will be a DAC based on the socioeconomic criterion and the indicator
|
||||||
|
|
||||||
|
__Updating `etl_score.py`__
|
||||||
|
- add the dataframe from the source to the ScoreETL constructor and add a line to read the dataframe into memory
|
||||||
|
- then, add the dataframe into the list of `census_tract_dfs`
|
||||||
|
- finally, add columns you want to include as percentiles to the `numeric_columns` list
|
||||||
|
|
||||||
|
__Updating `score_narwhal.py`__ (or whatever the score file is)
|
||||||
|
- per factor, add the columns that show the threshold and socioeconomic criterion is exceeded to the `eligibility_columns` list
|
||||||
|
- construct all columns specified in `field_names`, using the factor method as a guide
|
||||||
|
|
||||||
|
__Updating `constants.py`__
|
||||||
|
- add the columns' shortnames to the tiles dictionary (using Vim's UI sheet to guide short names)
|
||||||
|
- add the floats to the list of floats
|
||||||
|
|
||||||
|
__Updating `csv.yml` and `excel.yml`__
|
||||||
|
- make sure each column you want to be in the downloadable files is listed here
|
||||||
|
|
||||||
|
__Update the fixtures__
|
||||||
|
Follow the instructions on the repo to modify tiles so that `test_etl_post.py` doesn't fail. Then, confirm results.
|
|
@ -1,8 +1,5 @@
|
||||||
# Suffixes
|
# Suffixes
|
||||||
PERCENTILE_FIELD_SUFFIX = " (percentile)"
|
PERCENTILE_FIELD_SUFFIX = " (percentile)"
|
||||||
PERCENTILE_URBAN_RURAL_FIELD_SUFFIX = " (percentile urban/rural)"
|
|
||||||
MIN_MAX_FIELD_SUFFIX = " (min-max normalized)"
|
|
||||||
TOP_25_PERCENTILE_SUFFIX = " (top 25th percentile)"
|
|
||||||
ISLAND_AREAS_PERCENTILE_ADJUSTMENT_FIELD = " for island areas"
|
ISLAND_AREAS_PERCENTILE_ADJUSTMENT_FIELD = " for island areas"
|
||||||
|
|
||||||
# Geographic field names
|
# Geographic field names
|
||||||
|
@ -11,38 +8,6 @@ STATE_FIELD = "State/Territory"
|
||||||
COUNTY_FIELD = "County Name"
|
COUNTY_FIELD = "County Name"
|
||||||
|
|
||||||
# Score file field names
|
# Score file field names
|
||||||
SCORE_A = "Score A"
|
|
||||||
SCORE_B = "Score B"
|
|
||||||
SCORE_C = "Score C"
|
|
||||||
C_SOCIOECONOMIC = "Socioeconomic Factors"
|
|
||||||
C_SENSITIVE = "Sensitive populations"
|
|
||||||
C_ENVIRONMENTAL = "Environmental effects"
|
|
||||||
C_EXPOSURES = "Exposures"
|
|
||||||
SCORE_D = "Score D"
|
|
||||||
SCORE_E = "Score E"
|
|
||||||
SCORE_F_COMMUNITIES = "Score F (communities)"
|
|
||||||
SCORE_G = "Score G"
|
|
||||||
SCORE_G_COMMUNITIES = "Score G (communities)"
|
|
||||||
SCORE_H = "Score H"
|
|
||||||
SCORE_H_COMMUNITIES = "Score H (communities)"
|
|
||||||
SCORE_I = "Score I"
|
|
||||||
SCORE_I_COMMUNITIES = "Score I (communities)"
|
|
||||||
SCORE_K = "NMTC (communities)"
|
|
||||||
SCORE_K_COMMUNITIES = "Score K (communities)"
|
|
||||||
|
|
||||||
# Definition L fields
|
|
||||||
SCORE_L = "Definition L"
|
|
||||||
SCORE_L_COMMUNITIES = "Definition L (communities)"
|
|
||||||
L_CLIMATE = "Climate Factor (Definition L)"
|
|
||||||
L_ENERGY = "Energy Factor (Definition L)"
|
|
||||||
L_TRANSPORTATION = "Transportation Factor (Definition L)"
|
|
||||||
L_HOUSING = "Housing Factor (Definition L)"
|
|
||||||
L_POLLUTION = "Pollution Factor (Definition L)"
|
|
||||||
L_WATER = "Water Factor (Definition L)"
|
|
||||||
L_HEALTH = "Health Factor (Definition L)"
|
|
||||||
L_WORKFORCE = "Workforce Factor (Definition L)"
|
|
||||||
L_NON_WORKFORCE = "Any Non-Workforce Factor (Definition L)"
|
|
||||||
|
|
||||||
# Definition M fields
|
# Definition M fields
|
||||||
SCORE_M = "Definition M"
|
SCORE_M = "Definition M"
|
||||||
SCORE_M_COMMUNITIES = "Definition M (communities)"
|
SCORE_M_COMMUNITIES = "Definition M (communities)"
|
||||||
|
@ -85,25 +50,6 @@ WORKFORCE_SOCIO_INDICATORS_EXCEEDED = (
|
||||||
"Both workforce socioeconomic indicators exceeded"
|
"Both workforce socioeconomic indicators exceeded"
|
||||||
)
|
)
|
||||||
|
|
||||||
# For now, these are not used. Will delete after following up with Vim.
|
|
||||||
POLLUTION_SOCIO_INDICATORS_EXCEEDED = (
|
|
||||||
"Both pollution socioeconomic indicators exceeded"
|
|
||||||
)
|
|
||||||
CLIMATE_SOCIO_INDICATORS_EXCEEDED = (
|
|
||||||
"Both climate socioeconomic indicators exceeded"
|
|
||||||
)
|
|
||||||
ENERGY_SOCIO_INDICATORS_EXCEEDED = (
|
|
||||||
"Both energy socioeconomic indicators exceeded"
|
|
||||||
)
|
|
||||||
HOUSING_SOCIO_INDICATORS_EXCEEDED = (
|
|
||||||
"Both housing socioeconomic indicators exceeded"
|
|
||||||
)
|
|
||||||
WATER_SOCIO_INDICATORS_EXCEEDED = "Both water socioeconomic indicators exceeded"
|
|
||||||
|
|
||||||
HEALTH_SOCIO_INDICATORS_EXCEEDED = (
|
|
||||||
"Both health socioeconomic indicators exceeded"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Poverty / Income
|
# Poverty / Income
|
||||||
POVERTY_FIELD = "Poverty (Less than 200% of federal poverty line)"
|
POVERTY_FIELD = "Poverty (Less than 200% of federal poverty line)"
|
||||||
|
|
||||||
|
@ -156,6 +102,8 @@ EXPECTED_AGRICULTURE_LOSS_RATE_FIELD = (
|
||||||
EXPECTED_POPULATION_LOSS_RATE_FIELD = (
|
EXPECTED_POPULATION_LOSS_RATE_FIELD = (
|
||||||
"Expected population loss rate (Natural Hazards Risk Index)"
|
"Expected population loss rate (Natural Hazards Risk Index)"
|
||||||
)
|
)
|
||||||
|
FUTURE_FLOOD_RISK_FIELD = "Share of properties at risk of flood in 30 years"
|
||||||
|
FUTURE_WILDFIRE_RISK_FIELD = "Share of properties at risk of fire in 30 years"
|
||||||
|
|
||||||
# Environment
|
# Environment
|
||||||
DIESEL_FIELD = "Diesel particulate matter exposure"
|
DIESEL_FIELD = "Diesel particulate matter exposure"
|
||||||
|
@ -408,6 +356,15 @@ EXPECTED_BUILDING_LOSS_RATE_LOW_INCOME_FIELD = (
|
||||||
)
|
)
|
||||||
AGRICULTURAL_VALUE_BOOL_FIELD = "Contains agricultural value"
|
AGRICULTURAL_VALUE_BOOL_FIELD = "Contains agricultural value"
|
||||||
|
|
||||||
|
HIGH_FUTURE_FLOOD_RISK_LOW_INCOME_FIELD = (
|
||||||
|
f"Greater than or equal to the {PERCENTILE}th percentile for share of "
|
||||||
|
"properties at risk of flood in 30 years and is low income?"
|
||||||
|
)
|
||||||
|
HIGH_FUTURE_WILDFIRE_RISK_LOW_INCOME_FIELD = (
|
||||||
|
f"Greater than or equal to the {PERCENTILE}th percentile for "
|
||||||
|
"share of properties at risk of fire in 30 years and is low income?"
|
||||||
|
)
|
||||||
|
|
||||||
# Clean energy and efficiency
|
# Clean energy and efficiency
|
||||||
PM25_EXPOSURE_LOW_INCOME_FIELD = f"Greater than or equal to the {PERCENTILE}th percentile for PM2.5 exposure and is low income?"
|
PM25_EXPOSURE_LOW_INCOME_FIELD = f"Greater than or equal to the {PERCENTILE}th percentile for PM2.5 exposure and is low income?"
|
||||||
ENERGY_BURDEN_LOW_INCOME_FIELD = f"Greater than or equal to the {PERCENTILE}th percentile for energy burden and is low income?"
|
ENERGY_BURDEN_LOW_INCOME_FIELD = f"Greater than or equal to the {PERCENTILE}th percentile for energy burden and is low income?"
|
||||||
|
@ -670,6 +627,16 @@ LOW_LIFE_EXPECTANCY_PCTILE_THRESHOLD = (
|
||||||
UNEMPLOYMENT_PCTILE_THRESHOLD = (
|
UNEMPLOYMENT_PCTILE_THRESHOLD = (
|
||||||
f"Greater than or equal to the {PERCENTILE}th percentile for unemployment"
|
f"Greater than or equal to the {PERCENTILE}th percentile for unemployment"
|
||||||
)
|
)
|
||||||
|
HIGH_FUTURE_FLOOD_RISK_FIELD = (
|
||||||
|
f"Greater than or equal to the {PERCENTILE}th percentile for share of properties "
|
||||||
|
"at risk of flood in 30 years"
|
||||||
|
)
|
||||||
|
HIGH_FUTURE_WILDFIRE_RISK_FIELD = (
|
||||||
|
f"Greater than or equal to the {PERCENTILE}th percentile for share of properties "
|
||||||
|
"at risk of fire in 30 years"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
LINGUISTIC_ISOLATION_PCTILE_THRESHOLD = f"Greater than or equal to the {PERCENTILE}th percentile for households in linguistic isolation"
|
LINGUISTIC_ISOLATION_PCTILE_THRESHOLD = f"Greater than or equal to the {PERCENTILE}th percentile for households in linguistic isolation"
|
||||||
POVERTY_PCTILE_THRESHOLD = f"Greater than or equal to the {PERCENTILE}th percentile for households at or below 100% federal poverty level"
|
POVERTY_PCTILE_THRESHOLD = f"Greater than or equal to the {PERCENTILE}th percentile for households at or below 100% federal poverty level"
|
||||||
LOW_MEDIAN_INCOME_PCTILE_THRESHOLD = (
|
LOW_MEDIAN_INCOME_PCTILE_THRESHOLD = (
|
||||||
|
|
|
@ -122,8 +122,13 @@ class ScoreNarwhal(Score):
|
||||||
field_names.EXPECTED_POPULATION_LOSS_RATE_LOW_INCOME_FIELD,
|
field_names.EXPECTED_POPULATION_LOSS_RATE_LOW_INCOME_FIELD,
|
||||||
field_names.EXPECTED_AGRICULTURE_LOSS_RATE_LOW_INCOME_FIELD,
|
field_names.EXPECTED_AGRICULTURE_LOSS_RATE_LOW_INCOME_FIELD,
|
||||||
field_names.EXPECTED_BUILDING_LOSS_RATE_LOW_INCOME_FIELD,
|
field_names.EXPECTED_BUILDING_LOSS_RATE_LOW_INCOME_FIELD,
|
||||||
|
field_names.HIGH_FUTURE_FLOOD_RISK_LOW_INCOME_FIELD,
|
||||||
|
field_names.HIGH_FUTURE_WILDFIRE_RISK_LOW_INCOME_FIELD,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# TODO: When we refactor this... it's the same code over and over and over again
|
||||||
|
# We should make a function, _get_all_columns(), that returns all three of these columns
|
||||||
|
|
||||||
self.df[
|
self.df[
|
||||||
field_names.EXPECTED_POPULATION_LOSS_EXCEEDS_PCTILE_THRESHOLD
|
field_names.EXPECTED_POPULATION_LOSS_EXCEEDS_PCTILE_THRESHOLD
|
||||||
] = (
|
] = (
|
||||||
|
@ -152,6 +157,22 @@ class ScoreNarwhal(Score):
|
||||||
>= self.ENVIRONMENTAL_BURDEN_THRESHOLD
|
>= self.ENVIRONMENTAL_BURDEN_THRESHOLD
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.df[field_names.HIGH_FUTURE_FLOOD_RISK_FIELD] = (
|
||||||
|
self.df[
|
||||||
|
field_names.FUTURE_FLOOD_RISK_FIELD
|
||||||
|
+ field_names.PERCENTILE_FIELD_SUFFIX
|
||||||
|
]
|
||||||
|
>= self.ENVIRONMENTAL_BURDEN_THRESHOLD
|
||||||
|
)
|
||||||
|
|
||||||
|
self.df[field_names.HIGH_FUTURE_WILDFIRE_RISK_FIELD] = (
|
||||||
|
self.df[
|
||||||
|
field_names.FUTURE_WILDFIRE_RISK_FIELD
|
||||||
|
+ field_names.PERCENTILE_FIELD_SUFFIX
|
||||||
|
]
|
||||||
|
>= self.ENVIRONMENTAL_BURDEN_THRESHOLD
|
||||||
|
)
|
||||||
|
|
||||||
self.df[field_names.CLIMATE_THRESHOLD_EXCEEDED] = (
|
self.df[field_names.CLIMATE_THRESHOLD_EXCEEDED] = (
|
||||||
self.df[
|
self.df[
|
||||||
field_names.EXPECTED_POPULATION_LOSS_EXCEEDS_PCTILE_THRESHOLD
|
field_names.EXPECTED_POPULATION_LOSS_EXCEEDS_PCTILE_THRESHOLD
|
||||||
|
@ -162,6 +183,8 @@ class ScoreNarwhal(Score):
|
||||||
| self.df[
|
| self.df[
|
||||||
field_names.EXPECTED_BUILDING_LOSS_EXCEEDS_PCTILE_THRESHOLD
|
field_names.EXPECTED_BUILDING_LOSS_EXCEEDS_PCTILE_THRESHOLD
|
||||||
]
|
]
|
||||||
|
| self.df[field_names.HIGH_FUTURE_WILDFIRE_RISK_FIELD]
|
||||||
|
| self.df[field_names.HIGH_FUTURE_FLOOD_RISK_FIELD]
|
||||||
)
|
)
|
||||||
|
|
||||||
self.df[field_names.EXPECTED_POPULATION_LOSS_RATE_LOW_INCOME_FIELD] = (
|
self.df[field_names.EXPECTED_POPULATION_LOSS_RATE_LOW_INCOME_FIELD] = (
|
||||||
|
@ -183,6 +206,16 @@ class ScoreNarwhal(Score):
|
||||||
& self.df[field_names.FPL_200_SERIES_IMPUTED_AND_ADJUSTED]
|
& self.df[field_names.FPL_200_SERIES_IMPUTED_AND_ADJUSTED]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.df[field_names.HIGH_FUTURE_FLOOD_RISK_LOW_INCOME_FIELD] = (
|
||||||
|
self.df[field_names.HIGH_FUTURE_FLOOD_RISK_FIELD]
|
||||||
|
& self.df[field_names.FPL_200_SERIES_IMPUTED_AND_ADJUSTED]
|
||||||
|
)
|
||||||
|
|
||||||
|
self.df[field_names.HIGH_FUTURE_WILDFIRE_RISK_LOW_INCOME_FIELD] = (
|
||||||
|
self.df[field_names.HIGH_FUTURE_WILDFIRE_RISK_FIELD]
|
||||||
|
& self.df[field_names.FPL_200_SERIES_IMPUTED_AND_ADJUSTED]
|
||||||
|
)
|
||||||
|
|
||||||
self._increment_total_eligibility_exceeded(
|
self._increment_total_eligibility_exceeded(
|
||||||
climate_eligibility_columns,
|
climate_eligibility_columns,
|
||||||
skip_fips=constants.DROP_FIPS_FROM_NON_WTD_THRESHOLDS,
|
skip_fips=constants.DROP_FIPS_FROM_NON_WTD_THRESHOLDS,
|
||||||
|
@ -865,11 +898,6 @@ class ScoreNarwhal(Score):
|
||||||
|
|
||||||
self.df[field_names.THRESHOLD_COUNT] = 0
|
self.df[field_names.THRESHOLD_COUNT] = 0
|
||||||
|
|
||||||
# TODO: move this inside of
|
|
||||||
# `_create_low_income_and_low_college_attendance_threshold`
|
|
||||||
# and change the return signature of that method.
|
|
||||||
# Create a standalone field that captures the college attendance boolean
|
|
||||||
# threshold.
|
|
||||||
self.df[field_names.FPL_200_SERIES_IMPUTED_AND_ADJUSTED] = (
|
self.df[field_names.FPL_200_SERIES_IMPUTED_AND_ADJUSTED] = (
|
||||||
self.df[
|
self.df[
|
||||||
# UPDATE: Pull the imputed poverty statistic
|
# UPDATE: Pull the imputed poverty statistic
|
||||||
|
|
|
@ -1,13 +1,4 @@
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
from data_pipeline.score.score_a import ScoreA
|
|
||||||
from data_pipeline.score.score_b import ScoreB
|
|
||||||
from data_pipeline.score.score_c import ScoreC
|
|
||||||
from data_pipeline.score.score_f import ScoreF
|
|
||||||
from data_pipeline.score.score_g import ScoreG
|
|
||||||
from data_pipeline.score.score_h import ScoreH
|
|
||||||
from data_pipeline.score.score_i import ScoreI
|
|
||||||
from data_pipeline.score.score_k import ScoreK
|
|
||||||
from data_pipeline.score.score_l import ScoreL
|
|
||||||
from data_pipeline.score.score_m import ScoreM
|
from data_pipeline.score.score_m import ScoreM
|
||||||
from data_pipeline.score.score_narwhal import ScoreNarwhal
|
from data_pipeline.score.score_narwhal import ScoreNarwhal
|
||||||
|
|
||||||
|
@ -23,15 +14,6 @@ class ScoreRunner:
|
||||||
|
|
||||||
def calculate_scores(self) -> pd.DataFrame:
|
def calculate_scores(self) -> pd.DataFrame:
|
||||||
# Index scores
|
# Index scores
|
||||||
self.df = ScoreA(df=self.df).add_columns()
|
|
||||||
self.df = ScoreB(df=self.df).add_columns()
|
|
||||||
self.df = ScoreC(df=self.df).add_columns()
|
|
||||||
self.df = ScoreF(df=self.df).add_columns()
|
|
||||||
self.df = ScoreG(df=self.df).add_columns()
|
|
||||||
self.df = ScoreH(df=self.df).add_columns()
|
|
||||||
self.df = ScoreI(df=self.df).add_columns()
|
|
||||||
self.df = ScoreK(df=self.df).add_columns()
|
|
||||||
self.df = ScoreL(df=self.df).add_columns()
|
|
||||||
self.df = ScoreM(df=self.df).add_columns()
|
self.df = ScoreM(df=self.df).add_columns()
|
||||||
self.df = ScoreNarwhal(df=self.df).add_columns()
|
self.df = ScoreNarwhal(df=self.df).add_columns()
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue