This tutorial shows how to use the NavData
class, including how to initialize instances and perform basic operations.
[1]:
import numpy as np
import pandas as pd
import gnss_lib_py as glp
[2]:
# Get data path of example file
glp.make_dir("../data")
!wget https://raw.githubusercontent.com/Stanford-NavLab/gnss_lib_py/main/notebooks/tutorials/data/myreceiver.csv --quiet -nc -O "../data/myreceiver.csv"
data_path = "../data/myreceiver.csv"
NavData
Initializing
Create an empty NavData class instantiation
[3]:
empty_nav_data = glp.NavData()
print(empty_nav_data)
Empty NavData
Rows: []
Index: []
Create a NavData class from a csv file
[4]:
nav_data_csv = glp.NavData(csv_path=data_path)
print(nav_data_csv)
myTimestamp mySatId myPseudorange
0 10 10 270000001
1 10 14 270000007
2 10 7 270000004
3 10 3 270000005
4 11 10 270000002
5 11 14 270000008
6 11 7 270000003
7 11 3 270000004
Create an empty NavData class from a pandas DataFrame
[5]:
pd_df = pd.read_csv(data_path)
nav_data_pd = glp.NavData(pandas_df=pd_df)
print(nav_data_pd)
myTimestamp mySatId myPseudorange
0 10 10 270000001
1 10 14 270000007
2 10 7 270000004
3 10 3 270000005
4 11 10 270000002
5 11 14 270000008
6 11 7 270000003
7 11 3 270000004
Create an empty NavData class instantiation
[6]:
np_array = np.eye(4)
nav_data_np = glp.NavData(numpy_array=np_array)
print(nav_data_np)
0 1 2 3
0 1.0 0.0 0.0 0.0
1 0.0 1.0 0.0 0.0
2 0.0 0.0 1.0 0.0
3 0.0 0.0 0.0 1.0
Accessing values
In this example, the csv file that we have loaded has the following contents:
myTimestamp |
mySatId |
myPseudorange |
---|---|---|
10 |
G10 |
270000001 |
10 |
G14 |
270000007 |
10 |
G07 |
270000004 |
10 |
G03 |
270000005 |
11 |
G10 |
270000002 |
11 |
G14 |
270000008 |
11 |
G07 |
270000003 |
11 |
G03 |
270000004 |
NavData
stores the different types of measurements, like myTimestamp
as rows. So, each row contains the variable at different times/measurements. In this case, the myPseudorange
row contains values for different timestamps and satellite IDs
Values in rows can be accessed by using the name of the row or the number of the row
[7]:
nav_data_csv['myTimestamp']
[7]:
array([10, 10, 10, 10, 11, 11, 11, 11])
[8]:
nav_data_csv[0]
[8]:
array([10, 10, 10, 10, 11, 11, 11, 11])
By specifying a column number (or slice of columns) along with the row label/number, a sub part of the matrix can be accessed as well
[9]:
nav_data_csv['myPseudorange', :3]
[9]:
array([270000001, 270000007, 270000004])
To access multiple rows using labels, pass the labels as a list of strings or slice of numbers
[10]:
nav_data_csv[['myTimestamp', 'myPseudorange']]
[10]:
array([[1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01,
1.10000000e+01, 1.10000000e+01, 1.10000000e+01, 1.10000000e+01],
[2.70000001e+08, 2.70000007e+08, 2.70000004e+08, 2.70000005e+08,
2.70000002e+08, 2.70000008e+08, 2.70000003e+08, 2.70000004e+08]])
However, to ensure compatability with accessing operations, you cannot access string and numeric values jointly. This is to prevent unexpected behaviour that might result on performing mathematical operations with strings and numbers.
If you attempt to access a combination of strings and numbers, the method will return an AssertionError
[11]:
try:
nav_data_csv[0:2]
except AssertionError as err:
print(err)
Setting values
You can update values for existing rows by indexing those rows and assigning an array
[12]:
nav_data_csv['myPseudorange'] = 10*np.arange(8)
nav_data_csv['myPseudorange']
[12]:
array([ 0, 10, 20, 30, 40, 50, 60, 70])
You can also set individual values by accessing the specific rows and columns that you want to reassign
[13]:
nav_data_csv['myPseudorange', 2] = 111
nav_data_csv['myPseudorange']
[13]:
array([ 0, 10, 111, 30, 40, 50, 60, 70])
Setting new row
To set numeric values for a new row, access the row with the label name and assign the value to that row.
[14]:
nav_data_csv['new_row'] = np.arange(8)
nav_data_csv['new_row']
[14]:
array([0, 1, 2, 3, 4, 5, 6, 7])
New string rows can also be created similarly.
Note that while creating rows with string values, you must set the dtype
of the row to object
[15]:
nav_data_csv['new_string_row'] = np.array(['string1', 'string1', 'string1', 'string1',
'string2', 'string2', 'string2', 'string2'], dtype=object)
nav_data_csv['new_string_row']
[15]:
array(['string1', 'string1', 'string1', 'string1', 'string2', 'string2',
'string2', 'string2'], dtype=object)
Find rows, shape and length
You can see which rows are currently in NavData
using NavData.rows
. The number of columns can be viewed using len(NavData)
and the shape of the array can be viewed using NavData.shape
[16]:
nav_data_csv.rows
[16]:
['myTimestamp', 'mySatId', 'myPseudorange', 'new_row', 'new_string_row']
[17]:
nav_data_csv.shape
[17]:
(5, 8)
[18]:
len(nav_data_csv)
[18]:
8
[19]:
nav_data_csv.num_cols
[19]:
8
Removing rows or columns
To remove rows, use the NavData.remove()
method, specifying the rows and columns you want to remove.
[20]:
nav_data_removed = nav_data_csv.remove(rows=['new_row', 'new_string_row'])
print(nav_data_removed.rows)
print(nav_data_removed.shape)
['myTimestamp', 'mySatId', 'myPseudorange']
(3, 8)
[21]:
nav_data_removed = nav_data_csv.remove(cols=[0, 1])
print(nav_data_removed.shape)
(5, 6)
Copy
If you don’t specify any rows or columns, the entire NavData
will be copied
[22]:
nav_data_np_copy = nav_data_np.copy()
print('Original NavData array')
print(nav_data_np[:, :])
print('Copied NavData array')
print(nav_data_np_copy[:, :])
Original NavData array
[[1. 0. 0. 0.]
[0. 1. 0. 0.]
[0. 0. 1. 0.]
[0. 0. 0. 1.]]
Copied NavData array
[[1. 0. 0. 0.]
[0. 1. 0. 0.]
[0. 0. 1. 0.]
[0. 0. 0. 1.]]
Specifying rows, columns or both copies specified rows and columns.
Note that currently, rows and columns must be specified as lists.
[23]:
nav_data_np_copy = nav_data_np.copy(rows=[0,1], cols=list(range(4)))
print('Original NavData array')
print(nav_data_np[:, :])
print('Copied NavData array')
print(nav_data_np_copy[:, :])
Original NavData array
[[1. 0. 0. 0.]
[0. 1. 0. 0.]
[0. 0. 1. 0.]
[0. 0. 0. 1.]]
Copied NavData array
[[1. 0. 0. 0.]
[0. 1. 0. 0.]]
Convert to pd.DataFrame
and save to csv
You can use the NavData.to_csv()
method to save the data as a csv file and NavData.pandas_df()
to get the equivalent pd.DataFrame
[24]:
nav_data_pd.pandas_df()
[24]:
myTimestamp | mySatId | myPseudorange | |
---|---|---|---|
0 | 10 | 10 | 270000001 |
1 | 10 | 14 | 270000007 |
2 | 10 | 7 | 270000004 |
3 | 10 | 3 | 270000005 |
4 | 11 | 10 | 270000002 |
5 | 11 | 14 | 270000008 |
6 | 11 | 7 | 270000003 |
7 | 11 | 3 | 270000004 |
Looping over columns
You can loop over all columns using in-built looping functions. In this example, we terminate the loop after 3 runs for display clarity
[25]:
for col_idx, nav_data_col in enumerate(nav_data_pd):
print('Current column number', col_idx)
print('Current column')
print(nav_data_col)
if col_idx >= 3:
break
Current column number 0
Current column
myTimestamp mySatId myPseudorange
0 10 10 270000001
Current column number 1
Current column
myTimestamp mySatId myPseudorange
0 10 14 270000007
Current column number 2
Current column
myTimestamp mySatId myPseudorange
0 10 7 270000004
Current column number 3
Current column
myTimestamp mySatId myPseudorange
0 10 3 270000005