Repository navigation
Expand file tree
/
Copy patheva_data_analysis.py
More file actions
158 lines (126 loc) · 4.85 KB
/
Copy patheva_data_analysis.py
File metadata and controls
158 lines (126 loc) · 4.85 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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# Extra Vehicular Activity (eva in this source code) Data Analysis
import matplotlib.pyplot as plt
import pandas as pd
import sys
import re
def main(input_file, output_file, graph_file):
print("--START--")
# Read the data from JSON file
eva_data = read_json_to_dataframe(input_file)
# Calculate and add crew size to data
eva_data = add_crew_size_column(eva_data) # added this line
# Convert and export data to CSV file
write_dataframe_to_csv(eva_data, output_file)
# Sort dataframe by date ready to be plotted (date values are on x-axis)
eva_data.sort_values('date', inplace=True)
# Plot cumulative time spent in space over years
plot_cumulative_time_in_space(eva_data, graph_file)
print("--END--")
def read_json_to_dataframe(input_file):
"""
Read the data froma JSON into a pandas dataframe.
Clean the data by removing any rows where duration is missing.
Args:
input_file (file or stre): The file object or the path to the JSON file.
Returns:
eva_df (pd.DataFrame): The cleaned data as a dataframe structure.
"""
print(f'Reading JSON file {input_file}')
# Read the data from a JSON file into a Pandas dataframe
eva_df = pd.read_json(input_file, convert_dates=['date'], encoding='ascii')
eva_df['eva'] = eva_df['eva'].astype(float)
# Clean the data by removing any rows where duration is missing
eva_df.dropna(axis=0, subset=['duration', 'date'], inplace=True)
return eva_df
def write_dataframe_to_csv(df, output_file):
"""
Write the data frame to a csv file.
Args:
df (pd.DataFrame): The input dataframe.
output_file (str): The file object or path to output CSV file.
"""
print(f'Saving to CSV file {output_file}')
# Save dataframe to CSV file for later analysis
df.to_csv(output_file, index=False, encoding='utf-8')
def plot_cumulative_time_in_space(df, graph_file):
"""
Plot the cumulative time spent in space over years.
Conver the duration from strings to number of hours
Calculate the cumulative sums of durations
Generate a plot of cumulative time spent in space over years and save it to the specified location
Args:
df (pd.DataFrame): The input dataframe.
graph_file (str): The file object or path to output graph file.
"""
# Plot cumulative time spent in space over years
print(f'Plotting cumulative spacewalk duration and saving to {graph_file}')
df = add_duration_hours(df)
df['cumulative_time'] = df['duration_hours'].cumsum()
plt.plot(df['date'], df['cumulative_time'], 'ko-')
plt.xlabel('Year')
plt.ylabel('Total time spent in space to date (hours)')
plt.tight_layout()
plt.savefig(graph_file)
plt.show()
def text_to_duration(duration):
"""
Convert a text format duration "HH:MM" to duration in hours
Args:
duration (str): The text format duration
Returns:
duration_hours (float): The duration in hours
"""
hours, minutes = duration.split(":")
duration_hours = int(hours) + int(minutes)/60 # there is an intentional bug on this line (should divide by 60 not 6)
return duration_hours
def add_duration_hours(df):
"""
Add duration in hours (duration_hours) variable to the dataset
Args:
df (pd.DataFrame): The input dataframe.
Returns:
df_copy (pd.DataFrame): A copy of df with the new duration_hours variable added
"""
df_copy = df.copy()
df_copy["duration_hours"] = df_copy["duration"].apply(
text_to_duration
)
return df_copy
def calculate_crew_size(crew):
"""
Calculate the size of the crew for a single crew entry
Args:
crew (str): The text entry in the crew column containing a list of crew member names
Returns:
(int): The crew size
"""
if crew.split() == []:
return None
else:
return len(re.split(r';', crew))-1
def add_crew_size_column(df):
"""
Add crew_size column to the dataset containing the value of the crew size
Args:
df (pd.DataFrame): The input data frame.
Returns:
df_copy (pd.DataFrame): A copy of the dataframe df with the new crew_size variable added
"""
print('Adding crew size variable (crew_size) to dataset')
df_copy = df.copy()
df_copy["crew_size"] = df_copy["crew"].apply(
calculate_crew_size
)
return df_copy
# Main code
if __name__ == "__main__":
if len(sys.argv) < 3:
input_file = open('data/eva-data.json', 'r', encoding='ascii')
output_file = open('results/eva-data.csv', 'w', encoding='utf-8')
print('Using default input and output filenames.')
else:
input_file = sys.argv[1]
output_file = sys.argv[2]
print('Using custom input and output filenames.')
graph_file = 'results/cumulative_eva_graph.png'
main(input_file, output_file, graph_file)