Exploratory Analysis in Python
Use Python to explore and analyze data in Synnax
This guide will walk you through basic analysis on an example data set using Synnax. We’ll import the data set, explore it using the Synnax console, run analysis, and attach post-processed results.
Prerequisites
Start a local cluster
This guide assumes you’ve started a local cluster running on localhost:9090
using the
instructions here. You’re more than welcome to use a remote
cluster, but you’ll need to keep in mind that those connection parameters may be different
than the ones used in this guide.
Install the Synnax Console
We’re going to be using the Synnax console to do plot our data. To install it, follow the instructions here.
Install and authenticate the Python client
Finally, you’ll need to make sure you have the synnax
Python client installed and
authenticated with your cluster. A guide for doing so is available here.
Importing a data set
Our first step is to import a data set into Synnax. We’ll be using a sample CSV file we’ve generated just for this guide. To download it, run the following command:
curl -O https://raw.githubusercontent.com/synnaxlabs/synnax/main/docs/examples/april_9_wetdress.csv
Next, we’ll use the CLI to import our data set into Synnax. To do so, run
synnax ingest april_9_wetdress.csv
This command will begin an interactive import process that will prompt us with a few questions:
Welcome to the Synnax Ingestion CLI! Let's get started.
Using saved credentials.
Connection successful!
Would you like to ingest all cahnnels? [y/n] (y):
This question is asking if we want to import data for all columns in the file. We do, so we’ll hit enter. Next, Synnax will check if all of the columns in the CSV correspond with existing channels in our cluster:
Validating that channels exist...
The following channels were not found in the database:
┏━━━━━━━━━━━━━━━━━┓
┃ name ┃
┡━━━━━━━━━━━━━━━━━┩
│ ec_pressure_5 │
│ ec_pressure_7 │
│ ec_pressure_9 │
│ ec_pressure_11 │
│ ec_pressure_12 │
│ ec_pressure_14 │
│ ec_pressure_19 │
│ ec_tc_0 │
│ ec_tc_1 │
│ Time │
└─────────────────┘
Would you like to create them? [y/n] (y):
We do want to create them, so we’ll just hit enter.
Any any channels indexes (e.g. timestamps)? [y/n] (y):
Synnax is asking if any of the columns in the contain timestamps that tell us when samples were taken. These types of columns are called “indexes” and are used to execute queries by time range. If you’d like to read more about the different channel types in Synnax, see this page.
In our case, we have a ‘Time’ column that contains timestamps, so we’ll enter y
and hit
enter. Synnax will then ask us to select the name of our index column:
You can enter 'all' for all channels or a comma-separated list of:
1) Names (e.g. 'channel1, channel2, channel3')
2) Channel indices (e.g. '1, 2, 3')
3) A pattern to match (e.g. 'channel*, sensor*')
channels:
We’ll enter Time
, and move on to the next step:
Do all non-indexed channels have the same data rate or index? [y/n] (y):
This question asks us if our Time
column represents the timestamps for all of the other
columns in the data set. In our case, it does, so we’ll enter y
and continue. Synnax
will then ask us to enter the name of our time column:
Enter the name of an index or a data rate:
Again, we’ll enter Time
and continue. Then, Synnax will ask us about how we’d like
to assign data types to our channels:
Please select an option for assigning data types:
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ value ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ Guess data types from file │
│ Assign the same data type to all channels (excluding indexes) │
│ Group channels by data type │
└───────────────────────────────────────────────────────────────┘
Select an option # [0/1/2] (0):
We’ll select the first option, which will automatically guess the channel’s data types from the data in the file. We’ve now successfully created all of the channels in our data set.
The next time we import a data set with the same channels, Synnax will automatically detect the channels and skip this process.
Now, Synnax will ask us to confirm the starting timestamp for our data set.
Identified start timestamp for file as 2023-04-10T12:07:23.662716-04:00.
Is this correct? [y/n] (y):
This looks right, so we’ll hit enter. Finally, Synnax will ask us to name our data set, which we’ll use to reference it in future steps.
Please enter a name for the data set
Name (4_9_wetdress_data_cleaned.csv):
We’ll enter April 9 Wetdress
and hit enter. Synnax will then begin importing the data
set. When it’s done, we’ll see the following message:
━━━━━━━━━━━━━━━━━━ 100% 85740 out of 85570 samples - 7477108.2235981515 samples/s
Plotting our data set
Now that we’ve imported our data set, we can use Python to analyze it. We’ll create a new Python file and instantiate the Synnax client:
import synnax as sy
client = sy.Synnax()
Next, we’ll retrieve the range referencing the data we just imported:
data = client.ranges.retrieve("April 9 Wetdress")
ec_pressure_12
on our data set contains our flowmeter’s pressure differential readings
in psi. To make things easier to work with, we’ll alias ec_pressure_12
to flow_dp
:
data.ec_pressure_12.set_alias("flow_dp")
Next, we’ll filter our data set to only include samples where flow_dp
is greater than
5 psi
pressure_mask = data.flow_dp > 5
filtered_dp = data.flow_dp[pressure_mask]
filtered_time = data.Time[pressure_mask]
We’ll also clean up our Time
channel to use elapsed seconds instead of unix epoch
nanoseconds. We can use the sy.elapsed_seconds
utility to accomplish this:
elapsed_time = sy.elapsed_seconds(filtered_time)
Finally, we’ll plot our data with matplotlib:
import matplotlib.pyplot as plt
plt.plot(elapsed_time, filtered_dp)
plt.xlabel("Elapsed Time (s)")
plt.ylabel("Flow DP (psi)")
plt.show()
We’ll save this file as plot.py
and run it with the following command:
python plot.py
This will open a window with the following plot: