<jupyter_start><jupyter_text>`clean_lat_long()`: Clean and validate geographical coordinates  IntroductionThe function `clean_lat_long()` cleans a column containing latitudinal and/or longitudinal coordinates, and standardizes them in a desired format. The function `validate_lat_long()` validates either a single coordinate or a column of coordinates, returning True if the value is valid, and False otherwise.The following latitudinal and longitudinal formats are supported via the `output_format` parameter:* Decimal degrees (dd): 41.5* Decimal degrees hemisphere (ddh): "41.5° N"* Degrees minutes (dm): "41° 30′ N"* Degrees minutes seconds (dms): "41° 30′ 0″ N"Invalid parsing is handled with the `errors` parameter:* "coerce" (default), invalid parsing will be set as NaN* "ignore", then invalid parsing will return the input* "raise", then invalid parsing will raise an exceptionAfter cleaning, a **report** is printed that provides the following information:* How many values were cleaned (the value must be transformed)* How many values could not be parsed* And the data summary: how many values in the correct format, and how many values are null  The following sections demonstrate the functionality of `clean_lat_long()` and `validate_lat_long()`.   An example dirty dataset<jupyter_code>import pandas as pd
import numpy as np
df = pd.DataFrame({"messy_lat_long": 
                   [(41.5, -81.0), "41.5;-81.0", "41.5,-81.0", "41.5 -81.0", 
                    "41.5° N, 81.0° W", "41.5 S;81.0 E", "-41.5 S;81.0 E", 
                    "23 26m 22s N 23 27m 30s E", "23 26' 22\" N 23 27' 30\" E", 
                    "UT: N 39°20' 0'' / W 74°35' 0''", "hello", np.nan, "NULL"]
                  })
df<jupyter_output><empty_output><jupyter_text>1. Default `clean_lat_long()` By default, the `output_format` parameter is set to "dd" (decimal degrees) and the `errors` parameter is set to "coerce" (set NaN when parsing is invalid).<jupyter_code>from dataprep.clean import clean_lat_long
clean_lat_long(df, "messy_lat_long")<jupyter_output>Latitude and Longitude Cleaning Report:
	8 values cleaned (61.54%)
	2 values unable to be parsed (15.38%), set to NaN
Result contains 9 (69.23%) values in the correct format and 4 null values (30.77%)<jupyter_text>Note (41.5, -81.0) is considered not cleaned in the report since it's resulting format is the same as the input. Also, "-41.5 S;81.0 E" is invalid because if a coordinate has a hemisphere it cannot contain a negative decimal value.  2. Output formatsThis section demonstrates the supported latitudinal and longitudinal formats. decimal degrees hemisphere (ddh)<jupyter_code>clean_lat_long(df, "messy_lat_long", output_format="ddh")<jupyter_output>Latitude and Longitude Cleaning Report:
	8 values cleaned (61.54%)
	2 values unable to be parsed (15.38%), set to NaN
Result contains 9 (69.23%) values in the correct format and 4 null values (30.77%)<jupyter_text>degrees minutes (dm)<jupyter_code>clean_lat_long(df, "messy_lat_long", output_format="dm")<jupyter_output>Latitude and Longitude Cleaning Report:
	9 values cleaned (69.23%)
	2 values unable to be parsed (15.38%), set to NaN
Result contains 9 (69.23%) values in the correct format and 4 null values (30.77%)<jupyter_text>degrees minutes seconds (dms)<jupyter_code>clean_lat_long(df, "messy_lat_long", output_format="dms")<jupyter_output>Latitude and Longitude Cleaning Report:
	9 values cleaned (69.23%)
	2 values unable to be parsed (15.38%), set to NaN
Result contains 9 (69.23%) values in the correct format and 4 null values (30.77%)<jupyter_text>3. `split` parameterThe split parameter adds individual columns containing the cleaned latitude and longitude values to the given DataFrame.<jupyter_code>clean_lat_long(df, "messy_lat_long", split=True)<jupyter_output>Latitude and Longitude Cleaning Report:
	9 values cleaned (69.23%)
	2 values unable to be parsed (15.38%), set to NaN
Result contains 9 (69.23%) values in the correct format and 4 null values (30.77%)<jupyter_text>Split can be used along with different output formats.<jupyter_code>clean_lat_long(df, "messy_lat_long", split=True, output_format="dm")<jupyter_output>Latitude and Longitude Cleaning Report:
	9 values cleaned (69.23%)
	2 values unable to be parsed (15.38%), set to NaN
Result contains 9 (69.23%) values in the correct format and 4 null values (30.77%)<jupyter_text>4. `inplace` parameterThis just deletes the given column from the returned dataframe. A new column containing cleaned coordinates is added with a title in the format `"{original title}_clean"`.<jupyter_code>clean_lat_long(df, "messy_lat_long", inplace=True)<jupyter_output>Latitude and Longitude Cleaning Report:
	8 values cleaned (61.54%)
	2 values unable to be parsed (15.38%), set to NaN
Result contains 9 (69.23%) values in the correct format and 4 null values (30.77%)<jupyter_text>`inplace` and `split`<jupyter_code>clean_lat_long(df, "messy_lat_long", split=True, inplace=True)<jupyter_output>Latitude and Longitude Cleaning Report:
	9 values cleaned (69.23%)
	2 values unable to be parsed (15.38%), set to NaN
Result contains 9 (69.23%) values in the correct format and 4 null values (30.77%)<jupyter_text>5. Latitude and longitude coordinates in separate columns Clean latitude or longitude coordinates individually<jupyter_code>df = pd.DataFrame({"messy_lat": [" 30′ 0″ E", "41° 30′ N", "41 S", "80", "hello", "NA"]})
clean_lat_long(df, lat_col="messy_lat")<jupyter_output>Latitude and Longitude Cleaning Report:
	3 values cleaned (50.0%)
	2 values unable to be parsed (33.33%), set to NaN
Result contains 3 (50.0%) values in the correct format and 3 null values (50.0%)<jupyter_text>Combine and clean separate columnsLatitude and longitude values are counted separately in the report.<jupyter_code>df = pd.DataFrame({"messy_lat": ["30° E", "41° 30′ N", "41 S", "80", "hello", "NA"],
                      "messy_long": ["30° E", "41° 30′ N", "41 W", "80", "hello", "NA"]})
clean_lat_long(df, lat_col="messy_lat", long_col="messy_long")<jupyter_output>Latitude and Longitude Cleaning Report:
	6 values cleaned (100.0%)
	4 values unable to be parsed (66.67%), set to NaN
Result contains 0 (0.0%) values in the correct format and 6 null values (100.0%)<jupyter_text>Clean separate columns and split the output<jupyter_code>clean_lat_long(df, lat_col="messy_lat", long_col="messy_long", split=True)<jupyter_output>Latitude and Longitude Cleaning Report:
	6 values cleaned (100.0%)
	4 values unable to be parsed (66.67%), set to NaN
Result contains 0 (0.0%) values in the correct format and 6 null values (100.0%)<jupyter_text>6. `validate_lat_long()` `validate_lat_long()` returns True when the input is a valid latitude or longitude value otherwise it returns False.Valid types are the same as `clean_lat_long()`.<jupyter_code>from dataprep.clean import validate_lat_long
print(validate_lat_long("41° 30′ 0″ N"))
print(validate_lat_long("41.5 S;81.0 E"))
print(validate_lat_long("-41.5 S;81.0 E"))
print(validate_lat_long((41.5, 81)))
print(validate_lat_long(41.5, lat_long=False, lat=True))
df = pd.DataFrame({"messy_lat_long": 
                   [(41.5, -81.0), "41.5;-81.0", "41.5,-81.0", "41.5 -81.0", 
                    "41.5° N, 81.0° W", "-41.5 S;81.0 E", 
                    "23 26m 22s N 23 27m 30s E", "23 26' 22\" N 23 27' 30\" E", 
                    "UT: N 39°20' 0'' / W 74°35' 0''", "hello", np.nan, "NULL"]
                  })
validate_lat_long(df["messy_lat_long"])<jupyter_output><empty_output><jupyter_text>Validate only one coordinate<jupyter_code>df = pd.DataFrame({"messy_lat": 
                   [41.5, "41.5", "41.5  ", 
                    "41.5° N", "-41.5 S", 
                    "23 26m 22s N", "23 26' 22\" N", 
                    "UT: N 39°20' 0''", "hello", np.nan, "NULL"]
                  })
validate_lat_long(df["messy_lat"], lat_long=False, lat=True)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11862906285569748, 'fraction_numerical': 0.06070570380675351, 'mean_word_length': 4.533939818054583, 'pattern_counts': {'":': 6, '<': 46, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '14', 'dir': 'jupyter-structured-clean-dedup', 'id': '400782', 'license': 'MIT', 'n_tokens_mistral': 2894, 'n_tokens_neox': 2516, 'n_words': 926, 'path': 'docs/source/user_guide/clean/clean_lat_long.ipynb', 'repo_name': 'juandavidospina/dataprep', 'size': '7907'}