Soil Index Subaccessor#

In this guide, the basics of the index subaccessor methods are presented. The index subaccessor is a collection of methods related to index property laboratory tests for each sample of each point in the DataFrame. The index properties of soil are the properties which help to assess the engineering behavior of soil and determine the classification of soil accurately. For information about the columns used by this subaccessor, see Soil Index Columns.

First, we import the necessary libraries,

In [1]: import pandas as pd

In [2]: import geotech_pandas

Next, we create a DataFrame with the following data,

In [3]: df = pd.DataFrame(
   ...:     {
   ...:         "point_id": ["BH-1", "BH-1", "BH-1", "BH-1"],
   ...:         "bottom": [1.0, 1.5, 3.0, 4.5],
   ...:         "moisture_content_mass_moist": [236.44, 154.40, 164.68, 135.61],
   ...:         "moisture_content_mass_dry": [174.40, 120.05, 134.31, 107.64],
   ...:         "moisture_content_mass_container": [22.20, 18.66, 20.27, 22.32],
   ...:         "liquid_limit_1_drops": [19, 18, 20, pd.NA],
   ...:         "liquid_limit_1_mass_moist": [13.91, 14.58, 16.24, pd.NA],
   ...:         "liquid_limit_1_mass_dry": [10.56, 11.23, 12.56, pd.NA],
   ...:         "liquid_limit_1_mass_container": [3.22, 3.28, 3.24, pd.NA],
   ...:         "liquid_limit_2_drops": [25, 25, 26, pd.NA],
   ...:         "liquid_limit_2_mass_moist": [18.48, 13.36, 12.23, pd.NA],
   ...:         "liquid_limit_2_mass_dry": [13.78, 10.45, 9.74, pd.NA],
   ...:         "liquid_limit_2_mass_container": [3.15, 3.27, 3.26, pd.NA],
   ...:         "liquid_limit_3_drops": [31, 32, 35, pd.NA],
   ...:         "liquid_limit_3_mass_moist": [21.38, 17.77, 13.40, pd.NA],
   ...:         "liquid_limit_3_mass_dry": [15.91, 13.67, 10.64, pd.NA],
   ...:         "liquid_limit_3_mass_container": [3.21, 3.24, 3.23, pd.NA],
   ...:         "plastic_limit_1_mass_moist": [12.26, 11.66, 13.22, pd.NA],
   ...:         "plastic_limit_1_mass_dry": [10.23, 9.89, 11.28, pd.NA],
   ...:         "plastic_limit_1_mass_container": [2.57, 2.99, 2.97, pd.NA],
   ...:         "plastic_limit_2_mass_moist": [11.17, 13.20, 17.01, pd.NA],
   ...:         "plastic_limit_2_mass_dry": [9.45, 11.01, 14.30, pd.NA],
   ...:         "plastic_limit_2_mass_container": [3.07, 2.56, 2.90, pd.NA],
   ...:     }
   ...: )
   ...: 

In [4]: df = df.convert_dtypes()

In [5]: df
Out[5]: 
  point_id  bottom  ...  plastic_limit_2_mass_dry  plastic_limit_2_mass_container
0     BH-1     1.0  ...                      9.45                            3.07
1     BH-1     1.5  ...                     11.01                            2.56
2     BH-1     3.0  ...                      14.3                             2.9
3     BH-1     4.5  ...                      <NA>                            <NA>

[4 rows x 23 columns]

Note

Notice that the df is reassigned with the result of convert_dtypes() method. This method converts the columns of df to the best possible dtypes that support NA to consistently represent missing data.

Use the dtypes property to show the current dtypes of df,

In [6]: df.dtypes
Out[6]: 
point_id                           string[python]
bottom                                    Float64
moisture_content_mass_moist               Float64
moisture_content_mass_dry                 Float64
moisture_content_mass_container           Float64
liquid_limit_1_drops                        Int64
liquid_limit_1_mass_moist                 Float64
liquid_limit_1_mass_dry                   Float64
liquid_limit_1_mass_container             Float64
liquid_limit_2_drops                        Int64
liquid_limit_2_mass_moist                 Float64
liquid_limit_2_mass_dry                   Float64
liquid_limit_2_mass_container             Float64
liquid_limit_3_drops                        Int64
liquid_limit_3_mass_moist                 Float64
liquid_limit_3_mass_dry                   Float64
liquid_limit_3_mass_container             Float64
plastic_limit_1_mass_moist                Float64
plastic_limit_1_mass_dry                  Float64
plastic_limit_1_mass_container            Float64
plastic_limit_2_mass_moist                Float64
plastic_limit_2_mass_dry                  Float64
plastic_limit_2_mass_container            Float64
dtype: object

Getting the moisture content#

The get_moisture_content() method returns a Series of moisture content values. This method requires the following columns:

Note

Since the result of this method is in the form of a percentage, it isn’t particularly strict in using g as the unit. However, it is still important to use a consistent unit across these columns.

In [7]: df["moisture_content"] = df.geotech.lab.index.get_moisture_content()

In [8]: df["moisture_content"]
Out[8]: 
0    40.762155
1    33.879081
2    26.631007
3    32.782466
Name: moisture_content, dtype: Float64

Getting the liquid limit#

The get_liquid_limit() method calculates and returns the liquid limit according to ASTM D4318 Method A Multipoint Method. The method interpolates the moisture content at 25 drops using the logarithm of the number of drops and the corresponding moisture content values. For 3 trials, this method requires the following columns:

Since there are no moisture content columns for each trial, we can use the get_moisture_content() method to calculate the moisture content for each trial and assign it back to the dataframe.

In [9]: df["liquid_limit_1_moisture_content"] = df.geotech.lab.index.get_moisture_content(prefix="liquid_limit_1")

In [10]: df["liquid_limit_1_moisture_content"]
Out[10]: 
0    45.640327
1    42.138365
2    39.484979
3         <NA>
Name: liquid_limit_1_moisture_content, dtype: Float64

In [11]: df["liquid_limit_2_moisture_content"] = df.geotech.lab.index.get_moisture_content(prefix="liquid_limit_2")

In [12]: df["liquid_limit_2_moisture_content"]
Out[12]: 
0    44.214487
1    40.529248
2    38.425926
3         <NA>
Name: liquid_limit_2_moisture_content, dtype: Float64

In [13]: df["liquid_limit_3_moisture_content"] = df.geotech.lab.index.get_moisture_content(prefix="liquid_limit_3")

In [14]: df["liquid_limit_3_moisture_content"]
Out[14]: 
0    43.070866
1    39.309684
2    37.246964
3         <NA>
Name: liquid_limit_3_moisture_content, dtype: Float64

Now that all required columns are present, we can call the get_liquid_limit() method to calculate the liquid limit for each sample in the dataframe.

In [15]: df["liquid_limit"] = df.geotech.lab.index.get_liquid_limit()

In [16]: df["liquid_limit"]
Out[16]: 
0    44.204815
1    40.525329
2    38.589278
3         <NA>
Name: liquid_limit, dtype: Float64

Getting the plastic limit#

The get_plastic_limit() method calculates and returns the plastic limit according to ASTM D4318. The plastic limit is the average of two moisture content measurements for the plastic limit test. This method requires the following columns:

Since there are no moisture content columns for each test, we can use the get_moisture_content() method to calculate the moisture content for each test and assign it back to the dataframe.

In [17]: df["plastic_limit_1_moisture_content"] = df.geotech.lab.index.get_moisture_content(prefix="plastic_limit_1")

In [18]: df["plastic_limit_1_moisture_content"]
Out[18]: 
0    26.501305
1    25.652174
2    23.345367
3         <NA>
Name: plastic_limit_1_moisture_content, dtype: Float64

In [19]: df["plastic_limit_2_moisture_content"] = df.geotech.lab.index.get_moisture_content(prefix="plastic_limit_2")

In [20]: df["plastic_limit_2_moisture_content"]
Out[20]: 
0    26.959248
1     25.91716
2     23.77193
3         <NA>
Name: plastic_limit_2_moisture_content, dtype: Float64

Now that all required columns are present, we can call the get_plastic_limit() method to calculate the plastic limit for each sample in the dataframe.

In [21]: df["plastic_limit"] = df.geotech.lab.index.get_plastic_limit()

In [22]: df["plastic_limit"]
Out[22]: 
0    26.730277
1    25.784667
2    23.558648
3         <NA>
Name: plastic_limit, dtype: Float64

Checking for nonplastic layers#

The is_nonplastic() method checks if a layer is nonplastic. A layer is considered nonplastic if the plastic limit is greater than or equal to the liquid limit, or if either the liquid limit or plastic limit is missing (NA). This method requires the following columns:

In [23]: df.geotech.lab.index.is_nonplastic()
Out[23]: 
0    False
1    False
2    False
3     True
Name: is_nonplastic, dtype: boolean

Getting the plasticity index#

The get_plasticity_index() method calculates the plasticity index as the difference between the liquid limit and the plastic limit. If a layer is nonplastic, the plasticity index is set to NA. This method requires the following columns:

In [24]: df["plasticity_index"] = df.geotech.lab.index.get_plasticity_index()

In [25]: df["plasticity_index"]
Out[25]: 
0    17.474538
1    14.740662
2    15.030629
3         <NA>
Name: plasticity_index, dtype: Float64

Getting the liquidity index#

The get_liquidity_index() method calculates the liquidity index as the ratio of the natural moisture content minus the plastic limit to the plasticity index. This method requires the following columns:

In [26]: df["liquidity_index"] = df.geotech.lab.index.get_liquidity_index()

In [27]: df["liquidity_index"]
Out[27]: 
0     0.80299
1    0.549121
2    0.204406
3        <NA>
Name: liquidity_index, dtype: Float64