Note
Go to the end to download the full example code.
Pandas Integration Example for ansys-units#
This example demonstrates how to use ansys-units with pandas DataFrames for unit-aware data analysis.
Basic Usage#
Create Series with units
print("=" * 70)
print("1. Creating Unit-Aware Series")
print("=" * 70)
# Method 1: Using dtype string
distances: Series = Series([1.0, 2.0, 3.0, 4.0, 5.0], dtype="quantity[m]")
print("\nDistances in meters:")
print(distances)
print(f"Dtype: {distances.dtype}")
# Method 2: Using QuantityDtype object
mass_dtype: QuantityDtype = QuantityDtype("kg")
masses: Series = Series([10.0, 20.0, 30.0, 40.0, 50.0], dtype=mass_dtype)
print("\nMasses in kilograms:")
print(masses)
======================================================================
1. Creating Unit-Aware Series
======================================================================
Distances in meters:
0 1.0 m
1 2.0 m
2 3.0 m
3 4.0 m
4 5.0 m
dtype: quantity[m]
Dtype: quantity[m]
Masses in kilograms:
0 10.0 kg
1 20.0 kg
2 30.0 kg
3 40.0 kg
4 50.0 kg
dtype: quantity[kg]
Unit Conversion#
Convert between different units
print("\n" + "=" * 70)
print("2. Unit Conversion")
print("=" * 70)
# Convert meters to feet
distances_ft: Series = distances.units.to("ft")
print("\nDistances converted to feet:")
print(distances_ft)
print(f"Dtype: {distances_ft.dtype}")
# Convert meters to centimeters
distances_cm: Series = distances.units.to("cm")
print("\nDistances converted to centimeters:")
print(distances_cm)
# Convert kilograms to grams
masses_g: Series = masses.units.to("g")
print("\nMasses converted to grams:")
print(masses_g)
======================================================================
2. Unit Conversion
======================================================================
Distances converted to feet:
0 3.280839895013124 ft
1 6.561679790026248 ft
2 9.842519685039372 ft
3 13.123359580052496 ft
4 16.404199475065617 ft
dtype: quantity[ft]
Dtype: quantity[ft]
Distances converted to centimeters:
0 100.0 cm
1 200.0 cm
2 300.0 cm
3 400.0 cm
4 500.0 cm
dtype: quantity[cm]
Masses converted to grams:
0 10000.0 g
1 20000.0 g
2 30000.0 g
3 40000.0 g
4 50000.0 g
dtype: quantity[g]
DataFrame Operations#
Working with multiple unit columns
print("\n" + "=" * 70)
print("3. Unit-Aware DataFrame")
print("=" * 70)
# Create DataFrame with multiple unit columns
df = DataFrame(
{
"specimen_id": [1, 2, 3, 4, 5],
"length": Series([10.0, 20.0, 30.0, 40.0, 50.0], dtype="quantity[mm]"),
"width": Series([5.0, 5.0, 5.0, 5.0, 5.0], dtype="quantity[mm]"),
"thickness": Series([2.0, 2.0, 2.0, 2.0, 2.0], dtype="quantity[mm]"),
"mass": Series([10.0, 20.0, 30.0, 40.0, 50.0], dtype="quantity[g]"),
"force": Series([100.0, 200.0, 300.0, 400.0, 500.0], dtype="quantity[N]"),
}
)
print("\nOriginal DataFrame:")
print(df)
# Get units summary
print("\nUnits Summary:")
units_summary = df.units.summary()
for col, unit in units_summary.items():
print(f" {col}: {unit}")
======================================================================
3. Unit-Aware DataFrame
======================================================================
Original DataFrame:
specimen_id length width thickness mass force
0 1 10.0 mm 5.0 mm 2.0 mm 10.0 g 100.0 N
1 2 20.0 mm 5.0 mm 2.0 mm 20.0 g 200.0 N
2 3 30.0 mm 5.0 mm 2.0 mm 30.0 g 300.0 N
3 4 40.0 mm 5.0 mm 2.0 mm 40.0 g 400.0 N
4 5 50.0 mm 5.0 mm 2.0 mm 50.0 g 500.0 N
Units Summary:
length: mm
width: mm
thickness: mm
mass: g
force: N
Batch Unit Conversion#
Convert multiple columns at once
print("\n" + "=" * 70)
print("4. Batch Unit Conversion")
print("=" * 70)
# Convert to different unit system
df_converted: DataFrame = df.units.to(
{"length": "cm", "width": "cm", "thickness": "cm", "mass": "kg"}
)
print("\nDataFrame with converted units:")
print(df_converted)
print("\nNew Units Summary:")
units_summary = df_converted.units.summary()
for col, unit in units_summary.items():
print(f" {col}: {unit}")
======================================================================
4. Batch Unit Conversion
======================================================================
DataFrame with converted units:
specimen_id length width thickness mass force
0 1 1.0 cm 0.5 cm 0.2 cm 0.01 kg 100.0 N
1 2 2.0 cm 0.5 cm 0.2 cm 0.02 kg 200.0 N
2 3 3.0 cm 0.5 cm 0.2 cm 0.03 kg 300.0 N
3 4 4.0 cm 0.5 cm 0.2 cm 0.04 kg 400.0 N
4 5 5.0 cm 0.5 cm 0.2 cm 0.05 kg 500.0 N
New Units Summary:
length: cm
width: cm
thickness: cm
mass: kg
force: N
Creating from Quantity Objects#
Build arrays from existing Quantity objects
print("\n" + "=" * 70)
print("5. Creating from Quantity Objects")
print("=" * 70)
# Create list of Quantity objects
quantities = [
Quantity(1.0, "m"),
Quantity(100.0, "cm"), # Will be converted to meters
Quantity(1000.0, "mm"), # Will be converted to meters
]
# Create array from quantities (they get normalized)
arr = QuantityArray._from_sequence(quantities)
series: Series = Series(arr)
print("\nSeries created from mixed-unit Quantities (normalized to first unit):")
print(series)
print(f"All values in: {series.dtype.units}")
======================================================================
5. Creating from Quantity Objects
======================================================================
Series created from mixed-unit Quantities (normalized to first unit):
0 1.0 m
1 1.0 m
2 1.0 m
dtype: quantity[m]
All values in: m
Indexing and Selection#
Access individual elements and slices
print("\n" + "=" * 70)
print("6. Indexing and Selection")
print("=" * 70)
# Get single element (returns Quantity)
first_distance: Series = distances.iloc[0]
print(f"\nFirst distance: {first_distance}")
print(f"Type: {type(first_distance)}")
print(f"Value: {first_distance.value} {first_distance.units}")
# Get slice (returns Series)
middle_distances: Series = distances.iloc[1:4]
print("\nMiddle distances (indices 1-3):")
print(middle_distances)
print(f"Type: {type(middle_distances)}")
# Boolean indexing
large_masses: Series = masses[masses.units.quantity.value > 25.0]
print("\nMasses greater than 25 kg:")
print(large_masses)
======================================================================
6. Indexing and Selection
======================================================================
First distance: 1.0 m
Type: <class 'ansys.units.quantity.Quantity'>
Value: 1.0 m
Middle distances (indices 1-3):
1 2.0 m
2 3.0 m
3 4.0 m
dtype: quantity[m]
Type: <class 'pandas.Series'>
Masses greater than 25 kg:
2 30.0 kg
3 40.0 kg
4 50.0 kg
dtype: quantity[kg]
Handling Missing Values#
Working with NaN values
print("\n" + "=" * 70)
print("7. Missing Values")
print("=" * 70)
# Create series with NaN
data_with_nan: Series = Series(
[1.0, 2.0, np.nan, 4.0, 5.0], dtype="quantity[m]"
) # noqa: E501
print("\nData with missing values:")
print(data_with_nan)
# Check for NaN
print("\nMissing value mask:")
print(data_with_nan.isna())
# Drop NaN values
clean_data: Series = data_with_nan.dropna()
print("\nData after dropping NaN:")
print(clean_data)
======================================================================
7. Missing Values
======================================================================
Data with missing values:
0 1.0 m
1 2.0 m
2 <NA>
3 4.0 m
4 5.0 m
dtype: quantity[m]
Missing value mask:
0 False
1 False
2 True
3 False
4 False
dtype: bool
Data after dropping NaN:
0 1.0 m
1 2.0 m
3 4.0 m
4 5.0 m
dtype: quantity[m]
Concatenation#
Combining Series with units
print("\n" + "=" * 70)
print("8. Concatenation")
print("=" * 70)
s1: Series = Series([1.0, 2.0, 3.0], dtype="quantity[m]")
s2: Series = Series([4.0, 5.0, 6.0], dtype="quantity[m]")
combined: Series = pd.concat([s1, s2], ignore_index=True)
print("\nConcatenated Series:")
print(combined)
print(f"Dtype preserved: {combined.dtype}")
======================================================================
8. Concatenation
======================================================================
Concatenated Series:
0 1.0 m
1 2.0 m
2 3.0 m
3 4.0 m
4 5.0 m
5 6.0 m
dtype: quantity[m]
Dtype preserved: quantity[m]
Reduction Operations#
Statistical operations that preserve units
print("\n" + "=" * 70)
print("9. Reduction Operations")
print("=" * 70)
measurements: Series = Series([10.5, 12.3, 11.8, 13.2, 10.9], dtype="quantity[mm]")
print("\nMeasurements:")
print(measurements)
# Sum
total: Series | float = measurements.sum()
print(f"\nSum: {total}")
# Mean
average: Series | float = measurements.mean()
print(f"Mean: {average}")
# Min and Max
minimum: Series | float = measurements.min()
maximum: Series | float = measurements.max()
print(f"Min: {minimum}")
print(f"Max: {maximum}")
# Standard deviation
std: Series | float = measurements.std()
print(f"Std Dev: {std}")
======================================================================
9. Reduction Operations
======================================================================
Measurements:
0 10.5 mm
1 12.3 mm
2 11.8 mm
3 13.2 mm
4 10.9 mm
dtype: quantity[mm]
Sum: 58.699999999999996 mm
Mean: 11.739999999999998 mm
Min: 10.5 mm
Max: 13.2 mm
Std Dev: 1.0830512453249845 mm
Real-World Example: Structural Analysis#
Analyzing beam deflection data
print("\n" + "=" * 70)
print("10. Real-World Example: Structural Analysis")
print("=" * 70)
# Simulated beam deflection data
analysis_df: DataFrame = DataFrame(
{
"beam_id": ["B001", "B002", "B003", "B004", "B005"],
"length": Series([5.0, 10.0, 15.0, 20.0, 25.0], dtype="quantity[m]"),
"load": Series(
[5000.0, 10000.0, 15000.0, 20000.0, 25000.0], dtype="quantity[N]"
),
"deflection": Series([2.5, 5.0, 7.5, 10.0, 12.5], dtype="quantity[mm]"),
"stress": Series([50.0, 100.0, 150.0, 200.0, 250.0], dtype="quantity[MPa]"),
}
)
print("\nBeam Analysis Data (SI units):")
print(analysis_df)
print("\nUnits:")
for col, unit in analysis_df.units.summary().items():
print(f" {col}: {unit}")
# Convert to imperial units for reporting
imperial_df: DataFrame = analysis_df.units.to(
{"length": "ft", "load": "lbf", "deflection": "in"}
)
print("\nBeam Analysis Data (Imperial units):")
print(imperial_df)
print("\nUnits:")
for col, unit in imperial_df.units.summary().items():
print(f" {col}: {unit}")
# Calculate load per unit length (would need arithmetic support)
print("\nAnalysis Summary:")
print(f" Total beams analyzed: {len(analysis_df)}")
print(f" Average beam length: {analysis_df['length'].mean()}")
print(f" Average load: {analysis_df['load'].mean()}")
print(f" Average deflection: {analysis_df['deflection'].mean()}")
print(f" Max stress: {analysis_df['stress'].max()}")
======================================================================
10. Real-World Example: Structural Analysis
======================================================================
Beam Analysis Data (SI units):
beam_id length load deflection stress
0 B001 5.0 m 5000.0 N 2.5 mm 50.0 MPa
1 B002 10.0 m 10000.0 N 5.0 mm 100.0 MPa
2 B003 15.0 m 15000.0 N 7.5 mm 150.0 MPa
3 B004 20.0 m 20000.0 N 10.0 mm 200.0 MPa
4 B005 25.0 m 25000.0 N 12.5 mm 250.0 MPa
Units:
length: m
load: N
deflection: mm
stress: MPa
Beam Analysis Data (Imperial units):
beam_id length ... deflection stress
0 B001 16.404199475065617 ft ... 0.0984251968503937 in 50.0 MPa
1 B002 32.808398950131235 ft ... 0.1968503937007874 in 100.0 MPa
2 B003 49.21259842519686 ft ... 0.2952755905511811 in 150.0 MPa
3 B004 65.61679790026247 ft ... 0.3937007874015748 in 200.0 MPa
4 B005 82.0209973753281 ft ... 0.4921259842519686 in 250.0 MPa
[5 rows x 5 columns]
Units:
length: ft
load: lbf
deflection: in
stress: MPa
Analysis Summary:
Total beams analyzed: 5
Average beam length: 15.0 m
Average load: 15000.0 N
Average deflection: 7.5 mm
Max stress: 250.0 MPa
Accessing Underlying Quantity#
Get the full Quantity object from a Series
print("\n" + "=" * 70)
print("11. Accessing Underlying Quantity")
print("=" * 70)
temps = Series([20.0, 25.0, 30.0, 35.0], dtype="quantity[C]")
print("\nTemperature Series:")
print(temps)
# Get as Quantity object
temp_quantity: TypeAlias = temps.units.quantity
print(f"\nAs Quantity object: {temp_quantity}")
print(f"Type: {type(temp_quantity)}")
print(f"Units: {temp_quantity.units}")
# Can use Quantity methods
temp_kelvin: temp_quantity = temp_quantity.to("K")
print(f"Converted to Kelvin: {temp_kelvin}")
======================================================================
11. Accessing Underlying Quantity
======================================================================
Temperature Series:
0 20.0 C
1 25.0 C
2 30.0 C
3 35.0 C
dtype: quantity[C]
As Quantity object: [20. 25. 30. 35.] C
Type: <class 'ansys.units.quantity.Quantity'>
Units: C
Converted to Kelvin: [293.15 298.15 303.15 308.15] K
Total running time of the script: (0 minutes 0.055 seconds)