Added Pandas logical operations nodes.
This commit is contained in:
+27
@@ -14,8 +14,10 @@ from .modules.cda.py_kv_float_create import PyKvFloatCreate
|
||||
from .modules.cda.py_kv_int_create import PyKvIntCreate
|
||||
from .modules.cda.py_kv_string_create import PyKvStringCreate
|
||||
from .modules.cda.py_string_to_datetime import PyStringToDatetime
|
||||
from .modules.cda.py_string_to_dict import PyStringToDict
|
||||
from .modules.cda.py_string_to_float import PyStringToFloat
|
||||
from .modules.cda.py_string_to_int import PyStringToInt
|
||||
from .modules.cda.py_string_to_list import PyStringToList
|
||||
from .modules.matplotlib.mpl_bar import MPLBar
|
||||
from .modules.matplotlib.mpl_line import MPLLine
|
||||
from .modules.matplotlib.mpl_pie_chart import MPLPieChart
|
||||
@@ -46,6 +48,7 @@ from .modules.pandas_wrapper.pandas_count import PandasCount
|
||||
from .modules.pandas_wrapper.pandas_cov import PandasCov
|
||||
from .modules.pandas_wrapper.pandas_create import PandasCreate
|
||||
from .modules.pandas_wrapper.pandas_create_from_dict import PandasCreateFromDict
|
||||
from .modules.pandas_wrapper.pandas_create_from_dict_index_list import PandasCreateFromDictIndexList
|
||||
from .modules.pandas_wrapper.pandas_create_from_multiple_dict import PandasCreateFromMultipleDict
|
||||
from .modules.pandas_wrapper.pandas_create_from_numpy import PandasCreateFromNumpy
|
||||
from .modules.pandas_wrapper.pandas_create_from_tensor import PandasCreateFromTensor
|
||||
@@ -62,11 +65,14 @@ from .modules.pandas_wrapper.pandas_div_scalar_int import PandasDivScalarInt
|
||||
from .modules.pandas_wrapper.pandas_div_series import PandasDivSeries
|
||||
from .modules.pandas_wrapper.pandas_drop_duplicates import PandasDropDuplicates
|
||||
from .modules.pandas_wrapper.pandas_dropna import PandasDropNA
|
||||
from .modules.pandas_wrapper.pandas_eq import PandasEq
|
||||
from .modules.pandas_wrapper.pandas_exp import PandasExp
|
||||
from .modules.pandas_wrapper.pandas_feature_split_to_numpy import PandasFeatureSplitToNumpy
|
||||
from .modules.pandas_wrapper.pandas_fillna_scalar_float import PandasFillNAScalarFloat
|
||||
from .modules.pandas_wrapper.pandas_fillna_scalar_int import PandasFillNAScalarInt
|
||||
from .modules.pandas_wrapper.pandas_ge import PandasGe
|
||||
from .modules.pandas_wrapper.pandas_group_by import PandasGroupBy
|
||||
from .modules.pandas_wrapper.pandas_gt import PandasGt
|
||||
from .modules.pandas_wrapper.pandas_head import PandasHead
|
||||
from .modules.pandas_wrapper.pandas_horizontal_concat import PandasHorizontalConcat
|
||||
from .modules.pandas_wrapper.pandas_horizontal_split import PandasHorizontalSplit
|
||||
@@ -86,6 +92,7 @@ from .modules.pandas_wrapper.pandas_index_to_string import PandasIndexToString
|
||||
from .modules.pandas_wrapper.pandas_isna import PandasIsNA
|
||||
from .modules.pandas_wrapper.pandas_join import PandasJoin
|
||||
from .modules.pandas_wrapper.pandas_kurtosis import PandasKurtosis
|
||||
from .modules.pandas_wrapper.pandas_le import PandasLe
|
||||
from .modules.pandas_wrapper.pandas_load_csv import PandasLoadCSV
|
||||
from .modules.pandas_wrapper.pandas_load_csv_with_encoding import PandasLoadCSVWithEncoding
|
||||
from .modules.pandas_wrapper.pandas_load_csv_with_index import PandasLoadCSVWithIndex
|
||||
@@ -96,6 +103,7 @@ from .modules.pandas_wrapper.pandas_loc_cell_string import PandasLocCellString
|
||||
from .modules.pandas_wrapper.pandas_loc_row_multiindex_dataframe import PandasLocRowMultiIndexDataFrame
|
||||
from .modules.pandas_wrapper.pandas_loc_row_series import PandasLocRowSeries
|
||||
from .modules.pandas_wrapper.pandas_log import PandasLog
|
||||
from .modules.pandas_wrapper.pandas_lt import PandasLt
|
||||
from .modules.pandas_wrapper.pandas_max import PandasMax
|
||||
from .modules.pandas_wrapper.pandas_mean import PandasMean
|
||||
from .modules.pandas_wrapper.pandas_median import PandasMedian
|
||||
@@ -106,6 +114,7 @@ from .modules.pandas_wrapper.pandas_mul import PandasMul
|
||||
from .modules.pandas_wrapper.pandas_mul_scalar_float import PandasMulScalarFloat
|
||||
from .modules.pandas_wrapper.pandas_mul_scalar_int import PandasMulScalarInt
|
||||
from .modules.pandas_wrapper.pandas_mul_series import PandasMulSeries
|
||||
from .modules.pandas_wrapper.pandas_ne import PandasNe
|
||||
from .modules.pandas_wrapper.pandas_pivot import PandasPivot
|
||||
from .modules.pandas_wrapper.pandas_pow import PandasPow
|
||||
from .modules.pandas_wrapper.pandas_pow_scalar_float import PandasPowScalarFloat
|
||||
@@ -298,6 +307,7 @@ NODE_CLASS_MAPPINGS: Dict[str, Type[T]] = {
|
||||
"PandasCov": PandasCov,
|
||||
"PandasCreate": PandasCreate,
|
||||
"PandasCreateFromDict": PandasCreateFromDict,
|
||||
"PandasCreateFromDictIndexList": PandasCreateFromDictIndexList,
|
||||
"PandasCreateFromMultipleDict": PandasCreateFromMultipleDict,
|
||||
"PandasCreateFromNumpy": PandasCreateFromNumpy,
|
||||
"PandasCreateFromTensor": PandasCreateFromTensor,
|
||||
@@ -314,11 +324,14 @@ NODE_CLASS_MAPPINGS: Dict[str, Type[T]] = {
|
||||
"PandasDivSeries": PandasDivSeries,
|
||||
"PandasDropDuplicates": PandasDropDuplicates,
|
||||
"PandasDropNA": PandasDropNA,
|
||||
"PandasEq": PandasEq,
|
||||
"PandasExp": PandasExp,
|
||||
"PandasFeatureSplitToNumpy": PandasFeatureSplitToNumpy,
|
||||
"PandasFillNAScalarFloat": PandasFillNAScalarFloat,
|
||||
"PandasFillNAScalarInt": PandasFillNAScalarInt,
|
||||
"PandasGe": PandasGe,
|
||||
"PandasGroupBy": PandasGroupBy,
|
||||
"PandasGt": PandasGt,
|
||||
"PandasHead": PandasHead,
|
||||
"PandasHorizontalConcat": PandasHorizontalConcat,
|
||||
"PandasHorizontalSplit": PandasHorizontalSplit,
|
||||
@@ -338,6 +351,7 @@ NODE_CLASS_MAPPINGS: Dict[str, Type[T]] = {
|
||||
"PandasIsNA": PandasIsNA,
|
||||
"PandasJoin": PandasJoin,
|
||||
"PandasKurtosis": PandasKurtosis,
|
||||
"PandasLe": PandasLe,
|
||||
"PandasLoadCSV": PandasLoadCSV,
|
||||
"PandasLoadCSVWithEncoding": PandasLoadCSVWithEncoding,
|
||||
"PandasLoadCSVWithIndex": PandasLoadCSVWithIndex,
|
||||
@@ -348,6 +362,7 @@ NODE_CLASS_MAPPINGS: Dict[str, Type[T]] = {
|
||||
"PandasLocRowMultiIndexDataFrame": PandasLocRowMultiIndexDataFrame,
|
||||
"PandasLocRowSeries": PandasLocRowSeries,
|
||||
"PandasLog": PandasLog,
|
||||
"PandasLt": PandasLt,
|
||||
"PandasMax": PandasMax,
|
||||
"PandasMean": PandasMean,
|
||||
"PandasMedian": PandasMedian,
|
||||
@@ -358,6 +373,7 @@ NODE_CLASS_MAPPINGS: Dict[str, Type[T]] = {
|
||||
"PandasMulScalarFloat": PandasMulScalarFloat,
|
||||
"PandasMulScalarInt": PandasMulScalarInt,
|
||||
"PandasMulSeries": PandasMulSeries,
|
||||
"PandasNe": PandasNe,
|
||||
"PandasPivot": PandasPivot,
|
||||
"PandasPow": PandasPow,
|
||||
"PandasPowScalarFloat": PandasPowScalarFloat,
|
||||
@@ -504,8 +520,10 @@ NODE_CLASS_MAPPINGS: Dict[str, Type[T]] = {
|
||||
"PyKvIntCreate": PyKvIntCreate,
|
||||
"PyKvStringCreate": PyKvStringCreate,
|
||||
"PyStringToDatetime": PyStringToDatetime,
|
||||
"PyStringToDict": PyStringToDict,
|
||||
"PyStringToFloat": PyStringToFloat,
|
||||
"PyStringToInt": PyStringToInt,
|
||||
"PyStringToList": PyStringToList,
|
||||
"SNSBar": SNSBar,
|
||||
"SNSBoxplot": SNSBoxplot,
|
||||
"SNSHeatmap": SNSHeatmap,
|
||||
@@ -559,6 +577,7 @@ NODE_DISPLAY_NAME_MAPPINGS: Dict[str, str] = {
|
||||
"PandasCov": "Pandas Cov",
|
||||
"PandasCreate": "Pandas Create",
|
||||
"PandasCreateFromDict": "Pandas Create From Dict",
|
||||
"PandasCreateFromDictIndexList": "Pandas Create From Dict Index List",
|
||||
"PandasCreateFromMultipleDict": "Pandas Create From Multiple Dict",
|
||||
"PandasCreateFromNumpy": "Pandas Create From Numpy",
|
||||
"PandasCreateFromTensor": "Pandas Create From Tensor",
|
||||
@@ -575,11 +594,14 @@ NODE_DISPLAY_NAME_MAPPINGS: Dict[str, str] = {
|
||||
"PandasDivSeries": "Pandas Div Series",
|
||||
"PandasDropDuplicates": "Pandas Drop Duplicates",
|
||||
"PandasDropNA": "Pandas Drop NA",
|
||||
"PandasEq": "Pandas Eq",
|
||||
"PandasExp": "Pandas Exp",
|
||||
"PandasFeatureSplitToNumpy": "Pandas Feature Split To Numpy",
|
||||
"PandasFillNAScalarFloat": "Pandas Fill NA Scalar Float",
|
||||
"PandasFillNAScalarInt": "Pandas Fill NA Scalar Int",
|
||||
"PandasGe": "Pandas Ge",
|
||||
"PandasGroupBy": "Pandas Group By",
|
||||
"PandasGt": "Pandas Gt",
|
||||
"PandasHead": "Pandas Head",
|
||||
"PandasHorizontalConcat": "Pandas Horizontal Concat",
|
||||
"PandasHorizontalSplit": "Pandas Horizontal Split",
|
||||
@@ -599,6 +621,7 @@ NODE_DISPLAY_NAME_MAPPINGS: Dict[str, str] = {
|
||||
"PandasIsNA": "Pandas Is NA",
|
||||
"PandasJoin": "Pandas Join",
|
||||
"PandasKurtosis": "Pandas Kurtosis",
|
||||
"PandasLe": "Pandas Le",
|
||||
"PandasLoadCSV": "Pandas Load CSV",
|
||||
"PandasLoadCSVWithEncoding": "Pandas Load CSV With Encoding",
|
||||
"PandasLoadCSVWithIndex": "Pandas Load CSV With Index",
|
||||
@@ -609,6 +632,7 @@ NODE_DISPLAY_NAME_MAPPINGS: Dict[str, str] = {
|
||||
"PandasLocRowMultiIndexDataFrame": "Pandas Loc Row MultiIndex DataFrame",
|
||||
"PandasLocRowSeries": "Pandas Loc Row Series",
|
||||
"PandasLog": "Pandas Log",
|
||||
"PandasLt": "Pandas Lt",
|
||||
"PandasMax": "Pandas Max",
|
||||
"PandasMean": "Pandas Mean",
|
||||
"PandasMedian": "Pandas Median",
|
||||
@@ -619,6 +643,7 @@ NODE_DISPLAY_NAME_MAPPINGS: Dict[str, str] = {
|
||||
"PandasMulScalarFloat": "Pandas Mul Scalar Float",
|
||||
"PandasMulScalarInt": "Pandas Mul Scalar Int",
|
||||
"PandasMulSeries": "Pandas Mul Series",
|
||||
"PandasNe": "Pandas Ne",
|
||||
"PandasPivot": "Pandas Pivot",
|
||||
"PandasPow": "Pandas Pow",
|
||||
"PandasPowScalarFloat": "Pandas Pow Scalar Float",
|
||||
@@ -765,8 +790,10 @@ NODE_DISPLAY_NAME_MAPPINGS: Dict[str, str] = {
|
||||
"PyKvIntCreate": "Py Kv Int Create",
|
||||
"PyKvStringCreate": "Py Kv String Create",
|
||||
"PyStringToDatetime": "Py String To Datetime",
|
||||
"PyStringToDict": "Py String To Dict",
|
||||
"PyStringToFloat": "Py String To Float",
|
||||
"PyStringToInt": "Py String To Int",
|
||||
"PyStringToList": "Py String To List",
|
||||
"SNSBar": "SNS Bar Chart",
|
||||
"SNSBoxplot": "SNS Boxplot",
|
||||
"SNSHeatmap": "SNS Heatmap",
|
||||
|
||||
@@ -109,6 +109,7 @@
|
||||
| [CDA Text Create](cda_text_create.md) | Creates a Python String using a value entered in a multi-line text field. |
|
||||
| [Pandas Create](pandas_create.md) | Creates a pandas DataFrame using values entered in the text field. |
|
||||
| [Pandas Create From Dict](pandas_create_from_dict.md) | Creates a pandas DataFrame from a Python dictionary. |
|
||||
| [Pandas Create From Dict Index List](pandas_create_from_dict_index_list.md) | Creates a pandas DataFrame from a Python dictionary and a list for index. |
|
||||
| [Pandas Create From Multiple Dict](pandas_create_from_multiple_dict.md) | Creates a pandas DataFrame from multiple Python dictionaries. |
|
||||
| [Pandas Create From Numpy](pandas_create_from_numpy.md) | Creates a pandas DataFrame from a NumPy ndarray. |
|
||||
| [Pandas Create From Tensor](pandas_create_from_tensor.md) | Creates a pandas DataFrame from a PyTorch tensor. |
|
||||
@@ -123,6 +124,15 @@
|
||||
| [Pandas Save CSV](pandas_save_csv.md) | Saves a PandasDataFrame to a CSV file. |
|
||||
| [Pandas Save JSON](pandas_save_json.md) | Saves a PandasDataFrame to a JSON file. |
|
||||
| [Pt Save Model](pt_save_model.md) | A wrapper class for saving a PyTorch model. |
|
||||
## Logical operations
|
||||
| Node | Description |
|
||||
| --- | --- |
|
||||
| [Pandas Eq](pandas_eq.md) | Determines whether each element in the first pandas DataFrame is equal to the corresponding element in the second DataFrame. |
|
||||
| [Pandas Ge](pandas_ge.md) | Determines whether each element in the first pandas DataFrame is greater than or equal to the corresponding element in the second DataFrame. |
|
||||
| [Pandas Gt](pandas_gt.md) | Determines whether each element in the first pandas DataFrame is greater than the corresponding element in the second DataFrame. |
|
||||
| [Pandas Le](pandas_le.md) | Determines whether each element in the first pandas DataFrame is less than or equal to the corresponding element in the second DataFrame. |
|
||||
| [Pandas Lt](pandas_lt.md) | Determines whether each element in the first pandas DataFrame is less than the corresponding element in the second DataFrame. |
|
||||
| [Pandas Ne](pandas_ne.md) | Determines whether each element in the first pandas DataFrame is not equal to the corresponding element in the second DataFrame. |
|
||||
## Math
|
||||
| Node | Description |
|
||||
| --- | --- |
|
||||
@@ -297,8 +307,10 @@
|
||||
| [Py Kv Int Create](py_kv_int_create.md) | Creates a Python dictionary with an string key and an integer value. |
|
||||
| [Py Kv String Create](py_kv_string_create.md) | Creates a Python dictionary with a string key and a string value. |
|
||||
| [Py String To Datetime](py_string_to_datetime.md) | Converts a Python string to a Python datetime.datetime. |
|
||||
| [Py String To Dict](py_string_to_dict.md) | Creates a Python dictionary using the string values entered in the text field. |
|
||||
| [Py String To Float](py_string_to_float.md) | Converts a Python string to a float. |
|
||||
| [Py String To Int](py_string_to_int.md) | Converts a Python string to an int. |
|
||||
| [Py String To List](py_string_to_list.md) | Creates a Python list using the string values entered in the text field. |
|
||||
## Summary statistics
|
||||
| Node | Description |
|
||||
| --- | --- |
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# Pandas Create From Dict
|
||||
Creates a pandas DataFrame from a Python dictionary.
|
||||
|
||||
Use `Py String To Dict` node to generate a dict from a string.
|
||||
|
||||
## Input
|
||||
| Name | Data type |
|
||||
|---|---|
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# Pandas Create From Dict Index List
|
||||
Creates a pandas DataFrame from a Python dictionary and a list for index.
|
||||
|
||||
Use `Py String To Dict` node to generate a dict for cell values from a string.
|
||||
Use `Py String To List` node to generate a list for index from a string.
|
||||
|
||||
## Input
|
||||
| Name | Data type |
|
||||
|---|---|
|
||||
| data | Pydict |
|
||||
| index | Pylist |
|
||||
|
||||
## Output
|
||||
| Data type |
|
||||
|---|
|
||||
| DataFrame |
|
||||
|
||||
<HR>
|
||||
Category: IO
|
||||
|
||||
ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved.
|
||||
@@ -0,0 +1,18 @@
|
||||
# Pandas Eq
|
||||
Determines whether each element in the first pandas DataFrame is equal to the corresponding element in the second DataFrame.
|
||||
|
||||
## Input
|
||||
| Name | Data type |
|
||||
|---|---|
|
||||
| a_dataframe | DataFrame |
|
||||
| b_dataframe | DataFrame |
|
||||
|
||||
## Output
|
||||
| Data type |
|
||||
|---|
|
||||
| DataFrame |
|
||||
|
||||
<HR>
|
||||
Category: Logical operations
|
||||
|
||||
ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved.
|
||||
@@ -0,0 +1,18 @@
|
||||
# Pandas Ge
|
||||
Determines whether each element in the first pandas DataFrame is greater than or equal to the corresponding element in the second DataFrame.
|
||||
|
||||
## Input
|
||||
| Name | Data type |
|
||||
|---|---|
|
||||
| a_dataframe | DataFrame |
|
||||
| b_dataframe | DataFrame |
|
||||
|
||||
## Output
|
||||
| Data type |
|
||||
|---|
|
||||
| DataFrame |
|
||||
|
||||
<HR>
|
||||
Category: Logical operations
|
||||
|
||||
ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved.
|
||||
@@ -0,0 +1,18 @@
|
||||
# Pandas Gt
|
||||
Determines whether each element in the first pandas DataFrame is greater than the corresponding element in the second DataFrame.
|
||||
|
||||
## Input
|
||||
| Name | Data type |
|
||||
|---|---|
|
||||
| a_dataframe | DataFrame |
|
||||
| b_dataframe | DataFrame |
|
||||
|
||||
## Output
|
||||
| Data type |
|
||||
|---|
|
||||
| DataFrame |
|
||||
|
||||
<HR>
|
||||
Category: Logical operations
|
||||
|
||||
ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved.
|
||||
@@ -0,0 +1,18 @@
|
||||
# Pandas Le
|
||||
Determines whether each element in the first pandas DataFrame is less than or equal to the corresponding element in the second DataFrame.
|
||||
|
||||
## Input
|
||||
| Name | Data type |
|
||||
|---|---|
|
||||
| a_dataframe | DataFrame |
|
||||
| b_dataframe | DataFrame |
|
||||
|
||||
## Output
|
||||
| Data type |
|
||||
|---|
|
||||
| DataFrame |
|
||||
|
||||
<HR>
|
||||
Category: Logical operations
|
||||
|
||||
ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved.
|
||||
@@ -0,0 +1,18 @@
|
||||
# Pandas Lt
|
||||
Determines whether each element in the first pandas DataFrame is less than the corresponding element in the second DataFrame.
|
||||
|
||||
## Input
|
||||
| Name | Data type |
|
||||
|---|---|
|
||||
| a_dataframe | DataFrame |
|
||||
| b_dataframe | DataFrame |
|
||||
|
||||
## Output
|
||||
| Data type |
|
||||
|---|
|
||||
| DataFrame |
|
||||
|
||||
<HR>
|
||||
Category: Logical operations
|
||||
|
||||
ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved.
|
||||
@@ -0,0 +1,18 @@
|
||||
# Pandas Ne
|
||||
Determines whether each element in the first pandas DataFrame is not equal to the corresponding element in the second DataFrame.
|
||||
|
||||
## Input
|
||||
| Name | Data type |
|
||||
|---|---|
|
||||
| a_dataframe | DataFrame |
|
||||
| b_dataframe | DataFrame |
|
||||
|
||||
## Output
|
||||
| Data type |
|
||||
|---|
|
||||
| DataFrame |
|
||||
|
||||
<HR>
|
||||
Category: Logical operations
|
||||
|
||||
ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved.
|
||||
@@ -0,0 +1,17 @@
|
||||
# Py String To Dict
|
||||
Creates a Python dictionary using the string values entered in the text field.
|
||||
|
||||
## Input
|
||||
| Name | Data type |
|
||||
|---|---|
|
||||
| data | String |
|
||||
|
||||
## Output
|
||||
| Data type |
|
||||
|---|
|
||||
| Pydict |
|
||||
|
||||
<HR>
|
||||
Category: Python wrapper
|
||||
|
||||
ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved.
|
||||
@@ -0,0 +1,17 @@
|
||||
# Py String To List
|
||||
Creates a Python list using the string values entered in the text field.
|
||||
|
||||
## Input
|
||||
| Name | Data type |
|
||||
|---|---|
|
||||
| data | String |
|
||||
|
||||
## Output
|
||||
| Data type |
|
||||
|---|
|
||||
| Pylist |
|
||||
|
||||
<HR>
|
||||
Category: Python wrapper
|
||||
|
||||
ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved.
|
||||
@@ -35,7 +35,7 @@ class CDAJSONCreate:
|
||||
data (str): String value in the text field.
|
||||
|
||||
Returns:
|
||||
tuple: A tuple containing a JSON string representation of the DataFrame.
|
||||
tuple: A tuple containing a JSON string.
|
||||
"""
|
||||
# Convert to JSON
|
||||
json_obj = json.loads(data)
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
from typing import Any, Dict
|
||||
import ast
|
||||
|
||||
class PyStringToDict:
|
||||
"""
|
||||
Creates a Python dictionary using the string values entered in the text field.
|
||||
|
||||
category: Python wrapper
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Dict[str, Any]:
|
||||
"""
|
||||
Defines the input types for the `create` function.
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: A dictionary specifying required input types.
|
||||
"""
|
||||
return {
|
||||
"required": {
|
||||
"data": ("STRING", {"multiline": True}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES: tuple = ("PYDICT",)
|
||||
FUNCTION: str = "f"
|
||||
CATEGORY: str = "Data Analysis"
|
||||
|
||||
def f(self, data: str) -> tuple:
|
||||
"""
|
||||
Creates a Python dictionary using the string values entered in the text field.
|
||||
|
||||
Args:
|
||||
data (str): String value in the text field.
|
||||
|
||||
Returns:
|
||||
tuple: A dict converted from the input string.
|
||||
"""
|
||||
d = ast.literal_eval(data)
|
||||
return (d,)
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
from typing import Any, List
|
||||
import ast
|
||||
|
||||
class PyStringToList:
|
||||
"""
|
||||
Creates a Python list using the string values entered in the text field.
|
||||
|
||||
category: Python wrapper
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> List[str]:
|
||||
"""
|
||||
Defines the input types for the `create` function.
|
||||
|
||||
Returns:
|
||||
List[str, Any]: A list specifying required input types.
|
||||
"""
|
||||
return {
|
||||
"required": {
|
||||
"data": ("STRING", {"multiline": True}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES: tuple = ("PYLIST",)
|
||||
FUNCTION: str = "f"
|
||||
CATEGORY: str = "Data Analysis"
|
||||
|
||||
def f(self, data: str) -> tuple:
|
||||
"""
|
||||
Creates a Python list using the string values entered in the text field.
|
||||
|
||||
Args:
|
||||
data (str): String value in the text field.
|
||||
|
||||
Returns:
|
||||
tuple: A list converted from the input string.
|
||||
"""
|
||||
d = ast.literal_eval(data)
|
||||
return (d,)
|
||||
|
||||
@@ -12,6 +12,8 @@ class PandasCreateFromDict:
|
||||
"""
|
||||
Creates a pandas DataFrame from a Python dictionary.
|
||||
|
||||
Use `Py String To Dict` node to generate a dict from a string.
|
||||
|
||||
category: IO
|
||||
"""
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
import os
|
||||
import sys
|
||||
from typing import Any, Dict, List
|
||||
import pandas as pd
|
||||
|
||||
PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", ".."))
|
||||
MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules")
|
||||
sys.path.append(MODULE_ROOT)
|
||||
from cda.utils import python_dict_first_value_len
|
||||
|
||||
class PandasCreateFromDictIndexList:
|
||||
"""
|
||||
Creates a pandas DataFrame from a Python dictionary and a list for index.
|
||||
|
||||
Use `Py String To Dict` node to generate a dict for cell values from a string.
|
||||
Use `Py String To List` node to generate a list for index from a string.
|
||||
|
||||
category: IO
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Dict[str, Any]:
|
||||
"""
|
||||
Defines the input types for the `create` function.
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: A dictionary specifying required input types.
|
||||
"""
|
||||
return {
|
||||
"required": {
|
||||
"data": ("PYDICT", {}),
|
||||
"index": ("PYLIST", {}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES: tuple = ("DATAFRAME",)
|
||||
FUNCTION: str = "f"
|
||||
CATEGORY: str = "Data Analysis"
|
||||
|
||||
def f(self, data: Dict, index: List) -> tuple:
|
||||
"""
|
||||
Creates a pandas DataFrame from a Python dictionary.
|
||||
|
||||
Args:
|
||||
data (Dict): A Python dictionary containing cell values.
|
||||
index (List): A Python list containing index.
|
||||
|
||||
Returns:
|
||||
tuple: A tuple containing a the DataFrame.
|
||||
"""
|
||||
if not data:
|
||||
df = pd.DataFrame() # Return an empty DataFrame if no data is provided.
|
||||
else:
|
||||
if not list:
|
||||
value_length = python_dict_first_value_len(data)
|
||||
df = pd.DataFrame(data, index=list(range(value_length)))
|
||||
else:
|
||||
df = pd.DataFrame(data, index=index)
|
||||
return (df,)
|
||||
@@ -0,0 +1,43 @@
|
||||
from typing import Any, Dict
|
||||
import pandas as pd
|
||||
|
||||
|
||||
class PandasEq:
|
||||
"""
|
||||
Determines whether each element in the first pandas DataFrame is equal to the corresponding element in the second DataFrame.
|
||||
|
||||
category: Logical operations
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Dict[str, Any]:
|
||||
"""
|
||||
Defines the input types for the function.
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: A dictionary specifying required input types.
|
||||
"""
|
||||
return {
|
||||
"required": {
|
||||
"a_dataframe": ("DATAFRAME", {}),
|
||||
"b_dataframe": ("DATAFRAME", {})
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES: tuple = ("DATAFRAME",)
|
||||
FUNCTION: str = "f"
|
||||
CATEGORY: str = "Data Analysis"
|
||||
|
||||
def f(self, a_dataframe: pd.DataFrame, b_dataframe: pd.DataFrame) -> tuple:
|
||||
"""
|
||||
Determines whether each element in the first pandas DataFrame is equal to the corresponding element in the second DataFrame.
|
||||
|
||||
Args:
|
||||
a_dataframe (DataFrame): The left DataFrame.
|
||||
b_dataframe (DataFrame): The right DataFrame.
|
||||
|
||||
Returns:
|
||||
tuple: A tuple containing the DataFrame containing the result of operation.
|
||||
"""
|
||||
df_out = a_dataframe.eq(b_dataframe)
|
||||
return (df_out,)
|
||||
@@ -0,0 +1,43 @@
|
||||
from typing import Any, Dict
|
||||
import pandas as pd
|
||||
|
||||
|
||||
class PandasGe:
|
||||
"""
|
||||
Determines whether each element in the first pandas DataFrame is greater than or equal to the corresponding element in the second DataFrame.
|
||||
|
||||
category: Logical operations
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Dict[str, Any]:
|
||||
"""
|
||||
Defines the input types for the function.
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: A dictionary specifying required input types.
|
||||
"""
|
||||
return {
|
||||
"required": {
|
||||
"a_dataframe": ("DATAFRAME", {}),
|
||||
"b_dataframe": ("DATAFRAME", {})
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES: tuple = ("DATAFRAME",)
|
||||
FUNCTION: str = "f"
|
||||
CATEGORY: str = "Data Analysis"
|
||||
|
||||
def f(self, a_dataframe: pd.DataFrame, b_dataframe: pd.DataFrame) -> tuple:
|
||||
"""
|
||||
Determines whether each element in the first pandas DataFrame is greater than or equal to the corresponding element in the second DataFrame.
|
||||
|
||||
Args:
|
||||
a_dataframe (DataFrame): The left DataFrame.
|
||||
b_dataframe (DataFrame): The right DataFrame.
|
||||
|
||||
Returns:
|
||||
tuple: A tuple containing the DataFrame containing the result of operation.
|
||||
"""
|
||||
df_out = a_dataframe.ge(b_dataframe)
|
||||
return (df_out,)
|
||||
@@ -0,0 +1,43 @@
|
||||
from typing import Any, Dict
|
||||
import pandas as pd
|
||||
|
||||
|
||||
class PandasGt:
|
||||
"""
|
||||
Determines whether each element in the first pandas DataFrame is greater than the corresponding element in the second DataFrame.
|
||||
|
||||
category: Logical operations
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Dict[str, Any]:
|
||||
"""
|
||||
Defines the input types for the function.
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: A dictionary specifying required input types.
|
||||
"""
|
||||
return {
|
||||
"required": {
|
||||
"a_dataframe": ("DATAFRAME", {}),
|
||||
"b_dataframe": ("DATAFRAME", {})
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES: tuple = ("DATAFRAME",)
|
||||
FUNCTION: str = "f"
|
||||
CATEGORY: str = "Data Analysis"
|
||||
|
||||
def f(self, a_dataframe: pd.DataFrame, b_dataframe: pd.DataFrame) -> tuple:
|
||||
"""
|
||||
Determines whether each element in the first pandas DataFrame is greater than the corresponding element in the second DataFrame.
|
||||
|
||||
Args:
|
||||
a_dataframe (DataFrame): The left DataFrame.
|
||||
b_dataframe (DataFrame): The right DataFrame.
|
||||
|
||||
Returns:
|
||||
tuple: A tuple containing the DataFrame containing the result of operation.
|
||||
"""
|
||||
df_out = a_dataframe.gt(b_dataframe)
|
||||
return (df_out,)
|
||||
@@ -0,0 +1,43 @@
|
||||
from typing import Any, Dict
|
||||
import pandas as pd
|
||||
|
||||
|
||||
class PandasLe:
|
||||
"""
|
||||
Determines whether each element in the first pandas DataFrame is less than or equal to the corresponding element in the second DataFrame.
|
||||
|
||||
category: Logical operations
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Dict[str, Any]:
|
||||
"""
|
||||
Defines the input types for the function.
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: A dictionary specifying required input types.
|
||||
"""
|
||||
return {
|
||||
"required": {
|
||||
"a_dataframe": ("DATAFRAME", {}),
|
||||
"b_dataframe": ("DATAFRAME", {})
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES: tuple = ("DATAFRAME",)
|
||||
FUNCTION: str = "f"
|
||||
CATEGORY: str = "Data Analysis"
|
||||
|
||||
def f(self, a_dataframe: pd.DataFrame, b_dataframe: pd.DataFrame) -> tuple:
|
||||
"""
|
||||
Determines whether each element in the first pandas DataFrame is less than or equal to the corresponding element in the second DataFrame.
|
||||
|
||||
Args:
|
||||
a_dataframe (DataFrame): The left DataFrame.
|
||||
b_dataframe (DataFrame): The right DataFrame.
|
||||
|
||||
Returns:
|
||||
tuple: A tuple containing the DataFrame containing the result of operation.
|
||||
"""
|
||||
df_out = a_dataframe.le(b_dataframe)
|
||||
return (df_out,)
|
||||
@@ -0,0 +1,43 @@
|
||||
from typing import Any, Dict
|
||||
import pandas as pd
|
||||
|
||||
|
||||
class PandasLt:
|
||||
"""
|
||||
Determines whether each element in the first pandas DataFrame is less than the corresponding element in the second DataFrame.
|
||||
|
||||
category: Logical operations
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Dict[str, Any]:
|
||||
"""
|
||||
Defines the input types for the function.
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: A dictionary specifying required input types.
|
||||
"""
|
||||
return {
|
||||
"required": {
|
||||
"a_dataframe": ("DATAFRAME", {}),
|
||||
"b_dataframe": ("DATAFRAME", {})
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES: tuple = ("DATAFRAME",)
|
||||
FUNCTION: str = "f"
|
||||
CATEGORY: str = "Data Analysis"
|
||||
|
||||
def f(self, a_dataframe: pd.DataFrame, b_dataframe: pd.DataFrame) -> tuple:
|
||||
"""
|
||||
Determines whether each element in the first pandas DataFrame is less than the corresponding element in the second DataFrame.
|
||||
|
||||
Args:
|
||||
a_dataframe (DataFrame): The left DataFrame.
|
||||
b_dataframe (DataFrame): The right DataFrame.
|
||||
|
||||
Returns:
|
||||
tuple: A tuple containing the DataFrame containing the result of operation.
|
||||
"""
|
||||
df_out = a_dataframe.lt(b_dataframe)
|
||||
return (df_out,)
|
||||
@@ -0,0 +1,43 @@
|
||||
from typing import Any, Dict
|
||||
import pandas as pd
|
||||
|
||||
|
||||
class PandasNe:
|
||||
"""
|
||||
Determines whether each element in the first pandas DataFrame is not equal to the corresponding element in the second DataFrame.
|
||||
|
||||
category: Logical operations
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Dict[str, Any]:
|
||||
"""
|
||||
Defines the input types for the function.
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: A dictionary specifying required input types.
|
||||
"""
|
||||
return {
|
||||
"required": {
|
||||
"a_dataframe": ("DATAFRAME", {}),
|
||||
"b_dataframe": ("DATAFRAME", {})
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES: tuple = ("DATAFRAME",)
|
||||
FUNCTION: str = "f"
|
||||
CATEGORY: str = "Data Analysis"
|
||||
|
||||
def f(self, a_dataframe: pd.DataFrame, b_dataframe: pd.DataFrame) -> tuple:
|
||||
"""
|
||||
Determines whether each element in the first pandas DataFrame is not equal to the corresponding element in the second DataFrame.
|
||||
|
||||
Args:
|
||||
a_dataframe (DataFrame): The left DataFrame.
|
||||
b_dataframe (DataFrame): The right DataFrame.
|
||||
|
||||
Returns:
|
||||
tuple: A tuple containing the DataFrame containing the result of operation.
|
||||
"""
|
||||
df_out = a_dataframe.ne(b_dataframe)
|
||||
return (df_out,)
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
[project]
|
||||
name = "data-analysis"
|
||||
description = "Data analysis custom modules for ComfyUI – Integrates Pandas, Seaborn and Matplotlib into ComfyUI, featuring extensive PyTorch wrapper nodes for seamless tensor operations. Experimental PyTorch model training was added in v2.0."
|
||||
version = "2.0.8"
|
||||
version = "2.0.9"
|
||||
license = {file = "LICENSE"}
|
||||
|
||||
[project.urls]
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
import pandas as pd
|
||||
|
||||
PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", ".."))
|
||||
MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules")
|
||||
sys.path.append(MODULE_ROOT)
|
||||
from pandas_wrapper.pandas_create_from_dict_index_list import PandasCreateFromDictIndexList
|
||||
|
||||
class TestPandasCreateFromDictIndexList(unittest.TestCase):
|
||||
def setUp(self):
|
||||
"""Set up test data."""
|
||||
self.node = PandasCreateFromDictIndexList()
|
||||
self.test_cases = [
|
||||
# Test with a standard dictionary and provided index
|
||||
(
|
||||
{"a": [1, 2, 3], "b": [4, 5, 6]},
|
||||
["row1", "row2", "row3"],
|
||||
pd.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]}, index=["row1", "row2", "row3"])
|
||||
),
|
||||
# Test with an empty dictionary (should return an empty DataFrame)
|
||||
(
|
||||
{},
|
||||
["row1", "row2"],
|
||||
pd.DataFrame()
|
||||
),
|
||||
# Test with missing index (should use default range index)
|
||||
(
|
||||
{"a": [7, 8, 9]},
|
||||
None,
|
||||
pd.DataFrame({"a": [7, 8, 9]}, index=[0, 1, 2])
|
||||
),
|
||||
# Test with integer index values
|
||||
(
|
||||
{"x": [10, 20], "y": [30, 40]},
|
||||
[100, 101],
|
||||
pd.DataFrame({"x": [10, 20], "y": [30, 40]}, index=[100, 101])
|
||||
),
|
||||
# Test with a single column and mismatched index length (should raise an error)
|
||||
(
|
||||
{"c": [1, 2]},
|
||||
["only_one_row"],
|
||||
ValueError # Expecting an error because index length doesn't match data length
|
||||
),
|
||||
]
|
||||
|
||||
def test_create_dataframe(self):
|
||||
"""Test creating a pandas DataFrame from a dictionary with an index."""
|
||||
for data, index, expected in self.test_cases:
|
||||
with self.subTest(data=data, index=index):
|
||||
if expected is ValueError:
|
||||
with self.assertRaises(ValueError):
|
||||
self.node.f(data, index)
|
||||
else:
|
||||
retval = self.node.f(data, index)
|
||||
self.assertIsInstance(retval, tuple, "Return value should be a tuple.")
|
||||
self.assertEqual(len(retval), 1, "Return tuple should have a single DataFrame.")
|
||||
pd.testing.assert_frame_equal(retval[0], expected)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,58 @@
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
import pandas as pd
|
||||
|
||||
PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", ".."))
|
||||
MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules")
|
||||
sys.path.append(MODULE_ROOT)
|
||||
from pandas_wrapper.pandas_eq import PandasEq
|
||||
|
||||
class TestPandasEq(unittest.TestCase):
|
||||
def setUp(self):
|
||||
"""Set up test data."""
|
||||
self.node = PandasEq()
|
||||
self.test_cases = [
|
||||
# Test where all values are True (a == b)
|
||||
(
|
||||
pd.DataFrame({"a": [1.5, 2.5]}, index=["row1", "row2"]),
|
||||
pd.DataFrame({"a": [1.5, 2.5]}, index=["row1", "row2"]),
|
||||
pd.DataFrame({"a": [True, True]}, index=["row1", "row2"])
|
||||
),
|
||||
# Test with mixed float and integer (True for all)
|
||||
(
|
||||
pd.DataFrame({"a": [3.0, 4]}, index=[0, 1]), # Second value is an integer
|
||||
pd.DataFrame({"a": [3.0, 4]}, index=[0, 1]), # Second value is an integer
|
||||
pd.DataFrame({"a": [True, True]}, index=[0, 1])
|
||||
),
|
||||
# Test with integer column labels (True for all)
|
||||
(
|
||||
pd.DataFrame({1: [10.0, 20]}, index=[0, 1]), # Second value is an integer
|
||||
pd.DataFrame({1: [10.0, 20]}, index=[0, 1]), # Second value is an integer
|
||||
pd.DataFrame({1: [True, True]}, index=[0, 1])
|
||||
),
|
||||
# Test with a False case (a != b)
|
||||
(
|
||||
pd.DataFrame({"a": [7.0]}, index=["row1"]),
|
||||
pd.DataFrame({"a": [7.5]}, index=["row1"]),
|
||||
pd.DataFrame({"a": [False]}, index=["row1"])
|
||||
),
|
||||
# Another False case with an integer column label
|
||||
(
|
||||
pd.DataFrame({2: [9]}, index=["row1"]), # Integer value
|
||||
pd.DataFrame({2: [10]}, index=["row1"]), # Different integer value
|
||||
pd.DataFrame({2: [False]}, index=["row1"])
|
||||
),
|
||||
]
|
||||
|
||||
def test_eq_operation(self):
|
||||
"""Test equality operation between two pandas DataFrames."""
|
||||
for df_a, df_b, expected in self.test_cases:
|
||||
with self.subTest(df_a=df_a, df_b=df_b):
|
||||
retval = self.node.f(df_a, df_b)
|
||||
self.assertIsInstance(retval, tuple, "Return value should be a tuple.")
|
||||
self.assertEqual(len(retval), 1, "Return tuple should have a single DataFrame.")
|
||||
pd.testing.assert_frame_equal(retval[0], expected)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,58 @@
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
import pandas as pd
|
||||
|
||||
PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", ".."))
|
||||
MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules")
|
||||
sys.path.append(MODULE_ROOT)
|
||||
from pandas_wrapper.pandas_ge import PandasGe
|
||||
|
||||
class TestPandasGe(unittest.TestCase):
|
||||
def setUp(self):
|
||||
"""Set up test data."""
|
||||
self.node = PandasGe()
|
||||
self.test_cases = [
|
||||
# Test where all values are True (a >= b)
|
||||
(
|
||||
pd.DataFrame({"a": [2.0, 3.0]}, index=["row1", "row2"]),
|
||||
pd.DataFrame({"a": [1.5, 2.5]}, index=["row1", "row2"]),
|
||||
pd.DataFrame({"a": [True, True]}, index=["row1", "row2"])
|
||||
),
|
||||
# Test with equality and lt
|
||||
(
|
||||
pd.DataFrame({"a": [2.5, 4.5]}, index=[0, 1]),
|
||||
pd.DataFrame({"a": [3.0, 4.5]}, index=[0, 1]),
|
||||
pd.DataFrame({"a": [False, True]}, index=[0, 1])
|
||||
),
|
||||
# Test with integer column labels (True)
|
||||
(
|
||||
pd.DataFrame({1: [15.0, 25.0]}, index=[0, 1]),
|
||||
pd.DataFrame({1: [10.0, 20.0]}, index=[0, 1]),
|
||||
pd.DataFrame({1: [True, True]}, index=[0, 1])
|
||||
),
|
||||
# Test with a False case (a < b)
|
||||
(
|
||||
pd.DataFrame({"a": [7.0]}, index=["row1"]),
|
||||
pd.DataFrame({"a": [7.5]}, index=["row1"]),
|
||||
pd.DataFrame({"a": [False]}, index=["row1"])
|
||||
),
|
||||
# True case with an integer column label
|
||||
(
|
||||
pd.DataFrame({2: [9.5]}, index=["row1"]),
|
||||
pd.DataFrame({2: [9.5]}, index=["row1"]),
|
||||
pd.DataFrame({2: [True]}, index=["row1"])
|
||||
),
|
||||
]
|
||||
|
||||
def test_ge_operation(self):
|
||||
"""Test greater-than-or-equal operation between two pandas DataFrames."""
|
||||
for df_a, df_b, expected in self.test_cases:
|
||||
with self.subTest(df_a=df_a, df_b=df_b):
|
||||
retval = self.node.f(df_a, df_b)
|
||||
self.assertIsInstance(retval, tuple, "Return value should be a tuple.")
|
||||
self.assertEqual(len(retval), 1, "Return tuple should have a single DataFrame.")
|
||||
pd.testing.assert_frame_equal(retval[0], expected)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,58 @@
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
import pandas as pd
|
||||
|
||||
PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", ".."))
|
||||
MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules")
|
||||
sys.path.append(MODULE_ROOT)
|
||||
from pandas_wrapper.pandas_gt import PandasGt
|
||||
|
||||
class TestPandasGt(unittest.TestCase):
|
||||
def setUp(self):
|
||||
"""Set up test data."""
|
||||
self.node = PandasGt()
|
||||
self.test_cases = [
|
||||
# Test where all values are True
|
||||
(
|
||||
pd.DataFrame({"a": [2.5, 3.5]}, index=["row1", "row2"]),
|
||||
pd.DataFrame({"a": [2.0, 3.0]}, index=["row1", "row2"]),
|
||||
pd.DataFrame({"a": [True, True]}, index=["row1", "row2"])
|
||||
),
|
||||
# Test with mixed result
|
||||
(
|
||||
pd.DataFrame({"a": [3.6, 4.9]}, index=[0, 1]),
|
||||
pd.DataFrame({"a": [3.5, 5.0]}, index=[0, 1]),
|
||||
pd.DataFrame({"a": [True, False]}, index=[0, 1])
|
||||
),
|
||||
# Test with integer column labels
|
||||
(
|
||||
pd.DataFrame({1: [14.0, 26.0]}, index=[0, 1]),
|
||||
pd.DataFrame({1: [15.0, 25.0]}, index=[0, 1]),
|
||||
pd.DataFrame({1: [False, True]}, index=[0, 1])
|
||||
),
|
||||
# Test with a False case (a < b)
|
||||
(
|
||||
pd.DataFrame({"a": [6.0]}, index=["row1"]),
|
||||
pd.DataFrame({"a": [7.0]}, index=["row1"]),
|
||||
pd.DataFrame({"a": [False]}, index=["row1"])
|
||||
),
|
||||
# Another False case with an integer column label
|
||||
(
|
||||
pd.DataFrame({2: [7.5]}, index=["row1"]),
|
||||
pd.DataFrame({2: [8.0]}, index=["row1"]),
|
||||
pd.DataFrame({2: [False]}, index=["row1"])
|
||||
),
|
||||
]
|
||||
|
||||
def test_gt_operation(self):
|
||||
"""Test greater-than operation between two pandas DataFrames."""
|
||||
for df_a, df_b, expected in self.test_cases:
|
||||
with self.subTest(df_a=df_a, df_b=df_b):
|
||||
retval = self.node.f(df_a, df_b)
|
||||
self.assertIsInstance(retval, tuple, "Return value should be a tuple.")
|
||||
self.assertEqual(len(retval), 1, "Return tuple should have a single DataFrame.")
|
||||
pd.testing.assert_frame_equal(retval[0], expected)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,58 @@
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
import pandas as pd
|
||||
|
||||
PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", ".."))
|
||||
MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules")
|
||||
sys.path.append(MODULE_ROOT)
|
||||
from pandas_wrapper.pandas_le import PandasLe
|
||||
|
||||
class TestPandasLe(unittest.TestCase):
|
||||
def setUp(self):
|
||||
"""Set up test data."""
|
||||
self.node = PandasLe()
|
||||
self.test_cases = [
|
||||
# Test where all values are True
|
||||
(
|
||||
pd.DataFrame({"a": [1.5, 2.5]}, index=["row1", "row2"]),
|
||||
pd.DataFrame({"a": [2.0, 2.5]}, index=["row1", "row2"]),
|
||||
pd.DataFrame({"a": [True, True]}, index=["row1", "row2"])
|
||||
),
|
||||
# Test with integer (still True)
|
||||
(
|
||||
pd.DataFrame({"a": [3, 4]}, index=[0, 1]),
|
||||
pd.DataFrame({"a": [3, 4]}, index=[0, 1]),
|
||||
pd.DataFrame({"a": [True, True]}, index=[0, 1])
|
||||
),
|
||||
# Test with integer column labels (True)
|
||||
(
|
||||
pd.DataFrame({1: [10.0, 20.0]}, index=[0, 1]),
|
||||
pd.DataFrame({1: [15.0, 20.0]}, index=[0, 1]),
|
||||
pd.DataFrame({1: [True, True]}, index=[0, 1])
|
||||
),
|
||||
# Test with a False case (a > b)
|
||||
(
|
||||
pd.DataFrame({"a": [7.0]}, index=["row1"]),
|
||||
pd.DataFrame({"a": [6.5]}, index=["row1"]),
|
||||
pd.DataFrame({"a": [False]}, index=["row1"])
|
||||
),
|
||||
# Another False case with an integer column label
|
||||
(
|
||||
pd.DataFrame({2: [9.5]}, index=["row1"]),
|
||||
pd.DataFrame({2: [8.0]}, index=["row1"]),
|
||||
pd.DataFrame({2: [False]}, index=["row1"])
|
||||
),
|
||||
]
|
||||
|
||||
def test_le_operation(self):
|
||||
"""Test less-than-or-equal operation between two pandas DataFrames."""
|
||||
for df_a, df_b, expected in self.test_cases:
|
||||
with self.subTest(df_a=df_a, df_b=df_b):
|
||||
retval = self.node.f(df_a, df_b)
|
||||
self.assertIsInstance(retval, tuple, "Return value should be a tuple.")
|
||||
self.assertEqual(len(retval), 1, "Return tuple should have a single DataFrame.")
|
||||
pd.testing.assert_frame_equal(retval[0], expected)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,58 @@
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
import pandas as pd
|
||||
|
||||
PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", ".."))
|
||||
MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules")
|
||||
sys.path.append(MODULE_ROOT)
|
||||
from pandas_wrapper.pandas_lt import PandasLt
|
||||
|
||||
class TestPandasLt(unittest.TestCase):
|
||||
def setUp(self):
|
||||
"""Set up test data."""
|
||||
self.node = PandasLt()
|
||||
self.test_cases = [
|
||||
# Test where all values are True
|
||||
(
|
||||
pd.DataFrame({"a": [1.5, 2.5]}, index=["row1", "row2"]),
|
||||
pd.DataFrame({"a": [2.0, 3.0]}, index=["row1", "row2"]),
|
||||
pd.DataFrame({"a": [True, True]}, index=["row1", "row2"])
|
||||
),
|
||||
# Test with integer (still True)
|
||||
(
|
||||
pd.DataFrame({"a": [3, 40]}, index=[0, 1]),
|
||||
pd.DataFrame({"a": [4, 50]}, index=[0, 1]),
|
||||
pd.DataFrame({"a": [True, True]}, index=[0, 1])
|
||||
),
|
||||
# Test with integer column labels
|
||||
(
|
||||
pd.DataFrame({1: [10.0, 20.0]}, index=[0, 1]),
|
||||
pd.DataFrame({1: [15.0, 20.0]}, index=[0, 1]),
|
||||
pd.DataFrame({1: [True, False]}, index=[0, 1])
|
||||
),
|
||||
# Test with a False case (a >= b)
|
||||
(
|
||||
pd.DataFrame({"a": [7.0]}, index=["row1"]),
|
||||
pd.DataFrame({"a": [7.0]}, index=["row1"]),
|
||||
pd.DataFrame({"a": [False]}, index=["row1"])
|
||||
),
|
||||
# Another False case with an integer column label
|
||||
(
|
||||
pd.DataFrame({2: [9.5]}, index=["row1"]),
|
||||
pd.DataFrame({2: [8.0]}, index=["row1"]),
|
||||
pd.DataFrame({2: [False]}, index=["row1"])
|
||||
),
|
||||
]
|
||||
|
||||
def test_lt_operation(self):
|
||||
"""Test less-than operation between two pandas DataFrames."""
|
||||
for df_a, df_b, expected in self.test_cases:
|
||||
with self.subTest(df_a=df_a, df_b=df_b):
|
||||
retval = self.node.f(df_a, df_b)
|
||||
self.assertIsInstance(retval, tuple, "Return value should be a tuple.")
|
||||
self.assertEqual(len(retval), 1, "Return tuple should have a single DataFrame.")
|
||||
pd.testing.assert_frame_equal(retval[0], expected)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -0,0 +1,58 @@
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
import pandas as pd
|
||||
|
||||
PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", ".."))
|
||||
MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules")
|
||||
sys.path.append(MODULE_ROOT)
|
||||
from pandas_wrapper.pandas_ne import PandasNe
|
||||
|
||||
class TestPandasNe(unittest.TestCase):
|
||||
def setUp(self):
|
||||
"""Set up test data."""
|
||||
self.node = PandasNe()
|
||||
self.test_cases = [
|
||||
# Test where all values are True (a != b)
|
||||
(
|
||||
pd.DataFrame({"a": [1.5, 2.5]}, index=["row1", "row2"]),
|
||||
pd.DataFrame({"a": [2.0, 3.0]}, index=["row1", "row2"]),
|
||||
pd.DataFrame({"a": [True, True]}, index=["row1", "row2"])
|
||||
),
|
||||
# Test with mixed float and integer (True for all)
|
||||
(
|
||||
pd.DataFrame({"a": [3.0, 4]}, index=[0, 1]), # Second value is an integer
|
||||
pd.DataFrame({"a": [3.5, 5]}, index=[0, 1]), # Second value is an integer
|
||||
pd.DataFrame({"a": [True, True]}, index=[0, 1])
|
||||
),
|
||||
# Test with integer column labels (True for all)
|
||||
(
|
||||
pd.DataFrame({1: [10.0, 20]}, index=[0, 1]), # Second value is an integer
|
||||
pd.DataFrame({1: [15.0, 25]}, index=[0, 1]), # Second value is an integer
|
||||
pd.DataFrame({1: [True, True]}, index=[0, 1])
|
||||
),
|
||||
# Test with a False case (a == b)
|
||||
(
|
||||
pd.DataFrame({"a": [7.0]}, index=["row1"]),
|
||||
pd.DataFrame({"a": [7.0]}, index=["row1"]),
|
||||
pd.DataFrame({"a": [False]}, index=["row1"])
|
||||
),
|
||||
# Another False case with an integer column label
|
||||
(
|
||||
pd.DataFrame({2: [9]}, index=["row1"]), # Integer value
|
||||
pd.DataFrame({2: [9]}, index=["row1"]), # Integer value
|
||||
pd.DataFrame({2: [False]}, index=["row1"])
|
||||
),
|
||||
]
|
||||
|
||||
def test_ne_operation(self):
|
||||
"""Test not-equal operation between two pandas DataFrames."""
|
||||
for df_a, df_b, expected in self.test_cases:
|
||||
with self.subTest(df_a=df_a, df_b=df_b):
|
||||
retval = self.node.f(df_a, df_b)
|
||||
self.assertIsInstance(retval, tuple, "Return value should be a tuple.")
|
||||
self.assertEqual(len(retval), 1, "Return tuple should have a single DataFrame.")
|
||||
pd.testing.assert_frame_equal(retval[0], expected)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user