FancyArray Examples
The FancyArray class in the fancypy library provides a robust and flexible way to handle array data with enhanced functionality. This documentation covers the usage of the FancyArray class, including initialization, array manipulation, and array analysis.
Array Initialization
Creating a FancyArray
To create an instance of a FancyArray, simply initialize it with the necessary data. FancyArray can handle different types of data and provide various functionalities out of the box.
import numpy as np
from numpy.typing import NDArray
from power_grid_model_ds.fancypy import FancyArray
class FancyTestArray(FancyArray):
"""Test array with some attributes"""
id: NDArray[np.int_]
test_int: NDArray[np.int_]
test_float: NDArray[np.float64]
test_str: NDArray[np.str_]
test_bool: NDArray[np.bool_]
fancy_array = FancyTestArray(
id=[1, 2, 3],
test_int=[3, 0, 4],
test_float=[4.0, 4.0, 1.0],
test_str=["a", "c", "d"],
test_bool=[True, False, True],
)
This creates a FancyTestArray instance with integer, float, boolean and string columns.
Array Manipulation
Accessing Array Elements
You can access the elements of a FancyArray using standard indexing. The class supports both single and multiple column access.
# Accessing a single column
id_column = fancy_array["id"]
id_column = fancy_array.id
# Accessing multiple columns
subset = fancy_array[["id", "test_int"]]
Setting Attributes
Attributes of the FancyArray can be dynamically set and modified. Changes are reflected in the underlying data.
# Setting new values to a column
fancy_array.id = np.array([9, 9, 9])
fancy_array["id"] = np.array([9, 9, 9])
fancy_array.id = [9, 9, 9]
fancy_array["id"] = [9, 9, 9]
fancy_array.id = 9
fancy_array["id"] = 9
Preventing Deletion of Numpy Attributes
Certain attributes inherent to numpy arrays, like size, cannot be deleted from a FancyArray.
# Attempting to delete a numpy attribute raises an error
try:
del fancy_array.size
except AttributeError as e:
print(e)
property 'size' of 'FancyTestArray' object has no deleter
Array Analysis
Iterating Over Rows You can iterate over the rows of a FancyArray, and each row is also an instance of FancyArray.
for row in fancy_array:
print(row)
id | test_int | test_float | test_str | test_bool
9 | 3 | 4.0 | a | True
id | test_int | test_float | test_str | test_bool
9 | 0 | 4.0 | c | False
id | test_int | test_float | test_str | test_bool
9 | 4 | 1.0 | d | True
Analyzing Data
The FancyArray class allows for detailed data analysis. You can use various numpy functions and methods to perform analysis on the data.
# Example analysis: sum of a column
total = np.sum(fancy_array.test_int)
Handling Non-Existing Attributes
Attempting to access a non-existing attribute will raise an AttributeError.
try:
value = fancy_array.non_existing_attribute
except AttributeError as e:
print(e)
'numpy.ndarray' object has no attribute 'non_existing_attribute'
Subclassing FancyArray
You can create subclasses of FancyArray to add specific functionality or constraints, such as custom string lengths.
class CustomStrLengthArray(FancyArray):
test_str: NDArray[np.str_]
_str_lengths = {"test_str": 100}
custom_array = CustomStrLengthArray(test_str=["a" * 100])
Using fancypy
The fancypy library provides additional tools and utilities to enhance the functionality of FancyArray. These tools help with various operations such as data manipulation, validation, and transformation.
Importing fancypy
To use the functionalities provided by fancypy, you need to import the library along with FancyArray.
import numpy as np
from power_grid_model_ds import fancypy as fp
from power_grid_model_ds.fancypy import FancyArray
Example Functions
concatenate
The concatenate function combines multiple FancyArray instances into a single array. This is useful for merging datasets.
class FancyTestArray(FancyArray):
"""Test array with some attributes"""
id: NDArray[np.int_]
value: NDArray[np.int_]
# Creating two FancyTestArray instances
array1 = FancyTestArray(
id=[1, 2],
value=[10, 20],
)
array2 = FancyTestArray(
id=[3, 4],
value=[30, 40],
)
# Concatenating the arrays
concatenated_array = fp.concatenate(array1, array2)
print(concatenated_array)
id | value
1 | 10
2 | 20
3 | 30
4 | 40
unique
The unique function returns the unique elements of a FancyArray along a specified axis. This is similar to numpy’s unique function but tailored for FancyArray.
# Creating a FancyTestArray with duplicate values
fancy_array = FancyTestArray(
id=[1, 2, 2, 3],
value=[10, 20, 20, 30],
)
# Getting unique elements
unique_array = fp.unique(fancy_array, axis=0)
print(unique_array)
id | value
1 | 10
2 | 20
3 | 30
sort
The sort function sorts the elements of a FancyArray along a specified axis.
# Creating a FancyArray with unsorted values
fancy_array = FancyTestArray(
id=[3, 1, 2],
value=[30, 10, 20],
)
# Sorting the array by the 'id' column
sorted_array = fp.sort(fancy_array, axis=0)
print(sorted_array)
id | value
1 | 10
2 | 20
3 | 30
array_equal
The array_equal function checks whether two FancyArray instances are element-wise equal. This is useful for comparing datasets.
# Creating two FancyTestArray instances for comparison
array1 = FancyTestArray(
id=[1, 2, 3],
value=[10, 20, 30],
)
array2 = FancyTestArray(
id=[1, 2, 3],
value=[10, 20, 30],
)
# Checking if the arrays are equal
are_equal = fp.array_equal(array1, array2)
print(f"Are the arrays equal? {are_equal}")
Are the arrays equal? True
Using Filters
The FancyArray class provides various filtering capabilities to manipulate and analyze array data efficiently. This section covers how to use the filtering functions such as exclude, filter, and get based on the provided test files.
Excluding Elements
Exclude by ID
The exclude method allows you to remove elements from the array based on specified criteria. You can exclude elements by their ID.
# Exclude elements with ID 1
excluded_array = fancy_array.exclude(id=1)
Exclude by Value
You can also exclude elements based on the value of a specific attribute.
# Exclude elements where 'value' is 10
excluded_array = fancy_array.exclude(value=10)
print(excluded_array)
id | value
2 | 20
3 | 30
Exclude with Multiple Conditions
The exclude method supports logical operations to combine multiple conditions. By default, it uses the AND operation, but you can specify the OR operation using the mode_ parameter.
# Exclude elements where 'id'=1 or 'value'=20
excluded_array = fancy_array.exclude(id=1, value=20, mode_="OR")
print(excluded_array)
id | value
3 | 30
Filtering Elements
Filter by ID
The filter method allows you to select elements from the array based on specified criteria. Filtering by ID can be done as follows:
# Filter elements with ID 1
filtered_array = fancy_array.filter(id=1)
Filter by Value
Similar to the exclude method, you can filter elements based on the value of a specific attribute.
# Filter elements where 'value' is 20
filtered_array = fancy_array.filter(value=20)
Filter with Multiple Conditions
The filter method also supports logical operations for combining multiple conditions.
# Filter elements where 'id' is 1 or 'value' is 20
filtered_array = fancy_array.filter(id=1, value=20, mode_="OR")
print(filtered_array)
id | value
1 | 10
2 | 20
Getting Elements
Get by ID
The get method retrieves a single element from the array that matches the specified criteria. You can get elements by their ID.
# Get element with ID 1
element = fancy_array.get(id=1)
Get by Value
You can also retrieve elements based on the value of a specific attribute.
# Get element where 'value' is 20
element = fancy_array.get(value=20)
print(element)
id | value
2 | 20
Handling Multiple Matches
If the get method finds multiple elements that match the criteria, it raises a MultipleRecordsReturned exception. If no elements match, it raises a RecordDoesNotExist exception.
# Handling multiple matches
from power_grid_model_ds.errors import MultipleRecordsReturned, RecordDoesNotExist
fancy_array = FancyTestArray(
id=[1, 2, 3, 4],
value=[10, 20, 20, 30],
)
try:
element = fancy_array.get(value=20)
except MultipleRecordsReturned:
print("Multiple records found")
# Handling no matches
try:
element = fancy_array.get(value=99.0)
except RecordDoesNotExist:
print("No record found")
Multiple records found
No record found