Pandas

colab level3

After passing levels 1 and 2, you are ready to start this: Level 3 - spyndex + pandas!

Remember to install spyndex!

[ ]:
!pip install -U spyndex

Now, let’s start!

First, import spyndex and pandas:

[31]:
import spyndex
import pandas as pd

pandas.Series

We have all worked with pandas. Well, spyndex also works with pandas so you can continue using it! :)

Let’s use a pandas.DataFrame that is stored in the spyndex datasets: spectral:

[59]:
df = spyndex.datasets.open("spectral")

Each column of this dataset is the Surface Reflectance from Landsat 8 for 3 different classes. The samples were taken over Oporto:

[33]:
df.head()
[33]:
SR_B1 SR_B2 SR_B3 SR_B4 SR_B5 SR_B6 SR_B7 ST_B10 class
0 0.089850 0.100795 0.132227 0.165764 0.269054 0.306206 0.251949 297.328396 Urban
1 0.073859 0.086990 0.124404 0.160979 0.281264 0.267596 0.217917 297.107934 Urban
2 0.072938 0.086028 0.120994 0.140203 0.284220 0.258384 0.200098 297.436064 Urban
3 0.087733 0.103916 0.135981 0.163976 0.254479 0.259580 0.216735 297.203638 Urban
4 0.090593 0.109306 0.150350 0.181260 0.269535 0.273234 0.219554 297.097680 Urban

Here you can see the classes stored in the class column:

[34]:
df["class"].unique()
[34]:
array(['Urban', 'Water', 'Vegetation'], dtype=object)

Each column of the data frame is a pandas.Series data type:

[35]:
type(df["SR_B2"])
[35]:
pandas.core.series.Series

Well, we can use that to compute Spectral Indices with spyndex!

Since we have vegetation, water and urban classes, let’s compute 3 different indices, each one highlighting an specific class: NDVI, NDWI and NDBI:

[36]:
spyndex.indices.NDVI
[36]:
NDVI: Normalized Difference Vegetation Index (attributes = ['bands', 'contributor', 'date_of_addition', 'formula', 'long_name', 'reference', 'short_name', 'type'])
[37]:
spyndex.indices.NDWI
[37]:
NDWI: Normalized Difference Water Index (attributes = ['bands', 'contributor', 'date_of_addition', 'formula', 'long_name', 'reference', 'short_name', 'type'])
[38]:
spyndex.indices.NDBI
[38]:
NDBI: Normalized Difference Built-Up Index (attributes = ['bands', 'contributor', 'date_of_addition', 'formula', 'long_name', 'reference', 'short_name', 'type'])

What bands do we need?

[39]:
spyndex.indices.NDVI.bands
[39]:
('N', 'R')
[40]:
spyndex.indices.NDWI.bands
[40]:
('G', 'N')
[41]:
spyndex.indices.NDBI.bands
[41]:
('S1', 'N')

Green, Red, NIR and SWIR1 bands… easy!

[42]:
parameters = {
    "G": df["SR_B3"],
    "R": df["SR_B4"],
    "N": df["SR_B5"],
    "S1": df["SR_B6"],
}

With our dict of parameters ready we can compute the indices!

[43]:
idx = spyndex.computeIndex(["NDVI","NDWI","NDBI"],parameters)

And, what’s the data type of the result?

[44]:
print(f"idx type: {type(idx)}")
idx type: <class 'pandas.core.frame.DataFrame'>

That’s right! A pandas.DataFrame! Why? Because each computed spectral index is now a column (pandas.Series) of a new dataframe:

[45]:
idx.head()
[45]:
NDVI NDWI NDBI
0 0.237548 -0.340973 0.064584
1 0.271989 -0.386671 -0.024902
2 0.339326 -0.402815 -0.047615
3 0.216278 -0.303482 0.009923
4 0.195821 -0.283852 0.006815

If you want them diectly on the original dataframe as new columns, you just have to play with the code a little bit!

[60]:
indicesToCompute = ["NDVI","NDWI","NDBI"]
df[indicesToCompute] = spyndex.computeIndex(indicesToCompute,parameters)

Now, if you check you original dataframe, you should have the new indices there!

[61]:
df.head()
[61]:
SR_B1 SR_B2 SR_B3 SR_B4 SR_B5 SR_B6 SR_B7 ST_B10 class NDVI NDWI NDBI
0 0.089850 0.100795 0.132227 0.165764 0.269054 0.306206 0.251949 297.328396 Urban 0.237548 -0.340973 0.064584
1 0.073859 0.086990 0.124404 0.160979 0.281264 0.267596 0.217917 297.107934 Urban 0.271989 -0.386671 -0.024902
2 0.072938 0.086028 0.120994 0.140203 0.284220 0.258384 0.200098 297.436064 Urban 0.339326 -0.402815 -0.047615
3 0.087733 0.103916 0.135981 0.163976 0.254479 0.259580 0.216735 297.203638 Urban 0.216278 -0.303482 0.009923
4 0.090593 0.109306 0.150350 0.181260 0.269535 0.273234 0.219554 297.097680 Urban 0.195821 -0.283852 0.006815

Beautiful! Right?

Now, just for the sake of life, let’s make some visualizations!

[50]:
import seaborn as sns
import matplotlib.pyplot as plt

Define some colors for each one of the classes:

[49]:
colors = ["#E33F62","#3FDDE3","#4CBA4B"]

Now, let’s create a gorgeous pair grid!

[64]:
plt.figure(figsize = (15,15))
g = sns.PairGrid(df[['NDVI', 'NDWI', 'NDBI','class']],hue = "class",palette = sns.color_palette(colors))
g.map_lower(sns.scatterplot)
g.map_upper(sns.kdeplot,fill = True,alpha = .5)
g.map_diag(sns.kdeplot,fill = True)
g.add_legend()
plt.show()
<Figure size 1080x1080 with 0 Axes>
../_images/tutorials_pandas_40_1.png