-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprocess_input.py
More file actions
130 lines (114 loc) · 5.15 KB
/
Copy pathprocess_input.py
File metadata and controls
130 lines (114 loc) · 5.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/usr/bin/env python3
import matplotlib.pyplot as plt
import pandas as pd
import geospatial_conversion
def magnitude_of_completeness(df):
"""Removes data below the magnitude of completeness."""
moc = None
while type(moc) is not float:
try:
moc = input("Enter the magnitude of completeness or leave the input blank for no filtering: ")
moc = float(moc)
df = df.drop(df.loc[df["Magnitude"] < moc].index)
except ValueError:
if moc == "":
break
return df
def remove_outliers_distance_matrix(df, remove=0.01):
"""Removes outliers using a distance matrix analysis.
The parameter remove controls the fraction of data to be removed as outliers. Not feasible for large datasets."""
from scipy.spatial import distance_matrix
location_vectors = df.loc[:, ["X", "Y", "Z"]]
d_matrix = pd.DataFrame(distance_matrix(location_vectors, location_vectors), columns=df.index, index=df.index)
total_distances = d_matrix.assign(Total=d_matrix[:].sum())["Total"]
# sum of distances from individual earthquakes to all earthquakes
total_distance_threshold = total_distances.quantile(1-remove)
df = df[df.merge(total_distances, left_index=True, right_index=True)["Total"] < total_distance_threshold]
# select rows only in which the total distance is less than the threshold
return df
def remove_outliers_cropping(df):
"""Removes outliers using manual cropping."""
fig, (ax1, ax2, ax3) = plt.subplots(3)
fig.suptitle("Spread of Data in Spatial Dimensions")
ax1.hist(df.X, log=False, bins=100)
ax1.set_title("Easting")
ax1.set(xlabel="X (km)", ylabel="Number of Events")
ax2.hist(df.Y, log=False, bins=100)
ax2.set_title("Northing")
ax2.set(xlabel="Y (km)", ylabel="Number of Events")
ax3.hist(df.Z, log=False, bins=100)
ax3.set_title("Depth")
ax3.set(xlabel="Z (km)", ylabel="Number of Events")
plt.tight_layout() # padding so that all text fits on default window
plt.draw()
plt.show(block=False)
plt.pause(0.01)
x_min, x_max, y_min, y_max, z_min, z_max = None, None, None, None, None, None
while type(x_min) is not float:
try:
x_min = input("Enter minimum X value or leave the input blank for no cropping: ")
x_min = float(x_min)
df = df.drop(df.loc[df["X"] < x_min].index)
except ValueError:
if x_min == "":
break
while type(x_max) is not float:
try:
x_max = input("Enter maximum X value or leave the input blank for no cropping: ")
x_max = float(x_max)
df = df.drop(df.loc[df["X"] > x_max].index)
except ValueError:
if x_max == "":
break
while type(y_min) is not float:
try:
y_min = input("Enter minimum Y value or leave the input blank for no cropping: ")
y_min = float(y_min)
df = df.drop(df.loc[df["Y"] < y_min].index)
except ValueError:
if y_min == "":
break
while type(y_max) is not float:
try:
y_max = input("Enter maximum Y value or leave the input blank for no cropping: ")
y_max = float(y_max)
df = df.drop(df.loc[df["Y"] > y_max].index)
except ValueError:
if y_max == "":
break
while type(z_min) is not float:
try:
z_min = input("Enter minimum Z value or leave the input blank for no cropping: ")
z_min = float(z_min)
df = df.drop(df.loc[df["Z"] < z_min].index)
except ValueError:
if z_min == "":
break
while type(z_max) is not float:
try:
z_max = input("Enter maximum Z value or leave the input blank for no cropping: ")
z_max = float(z_max)
df = df.drop(df.loc[df["Z"] > z_max].index)
except ValueError:
if z_max == "":
break
plt.close()
return df
def process(file_name, mode="u"):
"""Converts data for statistical analysis as necessary. Expected file format is a csv file with the columns
"Year", "Month", "Day", "Hour", "Minute", "Second", "latitude", "Longitude", "Depth", and "Magnitude".
Depth is to be expressed in kilometres."""
df = pd.read_csv(file_name)
df = df.dropna() # removing entries with no associated values
df["Time"] = pd.to_datetime(df[["Year", "Month", "Day", "Hour", "Minute", "Second"]], infer_datetime_format=True)
df = df.drop(columns=["Year", "Month", "Day", "Hour", "Minute", "Second"]) # dropping redundant columns
if mode == "e": # earth mode
df["X"], df["Y"], df["Z"] = geospatial_conversion.get_cartesian(
df["Latitude"].to_numpy(), df["Longitude"].to_numpy(), df["Depth"].to_numpy())
elif mode == "u": # utm mode
df["X"], df["Y"], df["Z"] = geospatial_conversion.get_utm(
df["Latitude"].to_numpy(), df["Longitude"].to_numpy(), df["Depth"].to_numpy())
df = df.drop(columns=["Latitude", "Longitude", "Depth"]) # dropping redundant columns
df = magnitude_of_completeness(df)
df = remove_outliers_cropping(df)
return df