66import os
77import click
88
9- pd_converter = {
10- "0 or 1" : "Int8" ,
11- "bigint" : "Int64" ,
12- "binary" : "Int8" ,
13- "bit" : "Int8" ,
14- "char" : "category" ,
15- "date" : "category" ,
16- "datetime" : "category" ,
17- "decimal" : "float64" ,
18- "float" : "float64" ,
19- "int" : "Int64" ,
20- "nchar" : "category" ,
21- "nvarchar" : "category" ,
22- "real" : "float64" ,
23- "smalldatetime" : "category" ,
24- "smallint" : "Int32" ,
25- "tinyint" : "Int32" ,
26- "uniqueidentifier" : "category" ,
27- "varbinary" : "bytes" ,
28- "varchar" : "category" ,
29- }
30-
31- dtype_to_python = {
32- "Int8" : int ,
33- "Int32" : int ,
34- "Int64" : int ,
35- "bytes" : lambda x : bytes (x , "utf-8" ),
36- "float64" : float ,
37- "category" : str ,
38- }
9+ # convertion map between OED, numpy_nullable, pyarrow, python
10+ _converter_header = ["OED Data Type" , "numpy_nullable" , "pyarrow" , "python" ]
11+ _converter_list = [
12+ ["0 or 1" , "Int8" , "int8[pyarrow]" , int ],
13+ ["bigint" , "Int64" , "int64[pyarrow]" , int ],
14+ ["binary" , "Int8" , "int8[pyarrow]" , int ],
15+ ["bit" , "Int8" , "int8[pyarrow]" , int ],
16+ ["char" , "category" , "string[pyarrow]" , str ],
17+ ["date" , "category" , "string[pyarrow]" , str ],
18+ ["datetime" , "category" , "string[pyarrow]" , str ],
19+ ["decimal" , "float64" , "float64[pyarrow]" , float ],
20+ ["float" , "float64" , "float64[pyarrow]" , float ],
21+ ["int" , "Int64" , "int64[pyarrow]" , int ],
22+ ["nchar" , "category" , "string[pyarrow]" , str ],
23+ ["nvarchar" , "category" , "string[pyarrow]" , str ],
24+ ["real" , "float64" , "float64[pyarrow]" , float ],
25+ ["smalldatetime" , "category" , "string[pyarrow]" , str ],
26+ ["smallint" , "Int32" , "int32[pyarrow]" , int ],
27+ ["tinyint" , "Int32" , "int32[pyarrow]" , int ],
28+ ["uniqueidentifier" , "category" , "string[pyarrow]" , str ],
29+ ["varbinary" , "bytes" , "string[pyarrow]" , lambda x : bytes (x , "utf-8" )],
30+ ["varchar" , "category" , "string[pyarrow]" , str ],
31+ ]
32+ converter_df = pd .DataFrame (_converter_list , columns = _converter_header )
33+ pd_converter = converter_df [["OED Data Type" , "numpy_nullable" ]].set_index ("OED Data Type" )["numpy_nullable" ].to_dict ()
34+ pa_converter = converter_df [["OED Data Type" , "pyarrow" ]].set_index ("OED Data Type" )["pyarrow" ].to_dict ()
35+ dtype_to_python = converter_df [["OED Data Type" , "python" ]].set_index ("OED Data Type" )["python" ].to_dict ()
3936
4037# Directory containing the CSV files
4138source_csv_default = pathlib .Path (os .path .dirname (os .path .realpath (__file__ ))).parent .joinpath ('OpenExposureData' )
@@ -63,6 +60,7 @@ def _read_oed_data(sheet_name, basepath=source_csv_dir):
6360
6461
6562 ods_schema = {}
63+ ods_schema ["backend_dtype" ] = ['pd_dtype' , 'pa_dtype' ]
6664 ods_schema ["input_fields" ] = get_ods_input_fields (_read_oed_data ("OEDInputFields" ))
6765 ods_schema ["perils" ] = get_ods_perils (_read_oed_data ("PerilValues" ), _read_oed_data ("PerilsCovered" ))
6866 ods_schema ["occupancy" ] = get_occupancy (_read_oed_data ("OccupancyValues" ))
@@ -83,7 +81,6 @@ def _read_oed_data(sheet_name, basepath=source_csv_dir):
8381 with open (output_path , "w" ) as fp :
8482 json .dump (ods_schema , fp , indent = " " )
8583
86-
8784 print (f"JSON OED specification has been created from dir '{ source_csv_dir } '. Output saved to '{ output_path } '" )
8885
8986
@@ -102,20 +99,22 @@ def get_ods_input_fields(ods_fields_df):
10299 ods_fields_df = ods_fields_df .assign (
103100 pd_dtype = ods_fields_df ["Data Type" ]
104101 .str .split ("(" , n = 1 , expand = True )[0 ]
105- .map (pd_converter )
102+ .map (pd_converter ),
103+ pa_dtype = ods_fields_df ["Data Type" ]
104+ .str .split ("(" , n = 1 , expand = True )[0 ]
105+ .map (pa_converter )
106106 ).rename (columns = {"File Name" : "File Names" })
107107 ods_fields_df ["Case Insensitive Field Name" ] = ods_fields_df [
108108 "Input Field Name"
109109 ].str .lower ()
110110
111111 # check that to Data Type is missing from our converter
112- if ods_fields_df ["pd_dtype" ].isna ().any ():
112+ if ods_fields_df ["pd_dtype" ].isna ().any () or ods_fields_df [ "pa_dtype" ]. isna (). any () :
113113 raise ValueError (
114- f"missing pd_dtype for:\n "
115- f"""{ ods_fields_df .loc [ods_fields_df ['pd_dtype' ].isna (),
114+ f"missing dtype for:\n "
115+ f"""{ ods_fields_df .loc [( ods_fields_df ['pd_dtype' ].isna ()) | ( ods_fields_df [ "pa_dtype" ]. isna () ),
116116 ['File Name' , 'Input Field Name' , 'Type & Description' , 'Data Type' ]]} """
117117 )
118-
119118 # split ods_fields per File Name
120119 split_df = ods_fields_df ["File Names" ].str .split (";" ).apply (pd .Series ).stack ()
121120 split_df = (
@@ -125,7 +124,7 @@ def get_ods_input_fields(ods_fields_df):
125124
126125 ods_fields_df ["Valid value range" ] = ods_fields_df .apply (
127126 lambda row : extract_valid_value_range (
128- row ["Valid value range" ], dtype_to_python [row ["pd_dtype" ]]
127+ row ["Valid value range" ], dtype_to_python [row ["Data Type" ]. split ( "(" , 1 )[ 0 ]]
129128 ),
130129 axis = 1 ,
131130 )
@@ -271,7 +270,10 @@ def get_cr_field(cr_field_df):
271270 cr_field_df = cr_field_df .assign (
272271 pd_dtype = cr_field_df ["Data Type" ]
273272 .str .split ("(" , n = 1 , expand = True )[0 ]
274- .map (pd_converter )
273+ .map (pd_converter ),
274+ pa_dtype = cr_field_df ["Data Type" ]
275+ .str .split ("(" , n = 1 , expand = True )[0 ]
276+ .map (pa_converter )
275277 ).rename (columns = {"File Name" : "File Names" })
276278
277279 # split ods_fields per File Name
0 commit comments