diff --git a/__init__.py b/__init__.py index 71d4d8c..e8df448 100644 --- a/__init__.py +++ b/__init__.py @@ -41,6 +41,7 @@ from .modules.pandas_wrapper.pandas_at_set_float import PandasAtSetFloat from .modules.pandas_wrapper.pandas_at_set_int import PandasAtSetInt from .modules.pandas_wrapper.pandas_at_set_string import PandasAtSetString from .modules.pandas_wrapper.pandas_at_string import PandasAtString +from .modules.pandas_wrapper.pandas_boolean_index import PandasBooleanIndex from .modules.pandas_wrapper.pandas_columns import PandasColumns from .modules.pandas_wrapper.pandas_corr import PandasCorr from .modules.pandas_wrapper.pandas_cos import PandasCos @@ -53,6 +54,8 @@ from .modules.pandas_wrapper.pandas_create_from_multiple_dict import PandasCreat from .modules.pandas_wrapper.pandas_create_from_numpy import PandasCreateFromNumpy from .modules.pandas_wrapper.pandas_create_from_tensor import PandasCreateFromTensor from .modules.pandas_wrapper.pandas_create_series_from_dict import PandasCreateSeriesFromDict +from .modules.pandas_wrapper.pandas_create_series_from_list import PandasCreateSeriesFromList +from .modules.pandas_wrapper.pandas_create_series_from_list_index_list import PandasCreateSeriesFromListIndexList from .modules.pandas_wrapper.pandas_create_with_index import PandasCreateWithIndex from .modules.pandas_wrapper.pandas_crosstab import PandasCrosstab from .modules.pandas_wrapper.pandas_cummax import PandasCummax @@ -66,13 +69,19 @@ 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_eq_scalar_float import PandasEqScalarFloat +from .modules.pandas_wrapper.pandas_eq_scalar_int import PandasEqScalarInt 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_ge_scalar_float import PandasGeScalarFloat +from .modules.pandas_wrapper.pandas_ge_scalar_int import PandasGeScalarInt from .modules.pandas_wrapper.pandas_group_by import PandasGroupBy from .modules.pandas_wrapper.pandas_gt import PandasGt +from .modules.pandas_wrapper.pandas_gt_scalar_float import PandasGtScalarFloat +from .modules.pandas_wrapper.pandas_gt_scalar_int import PandasGtScalarInt 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 @@ -93,6 +102,8 @@ 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_le_scalar_float import PandasLeScalarFloat +from .modules.pandas_wrapper.pandas_le_scalar_int import PandasLeScalarInt 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 @@ -104,6 +115,8 @@ from .modules.pandas_wrapper.pandas_loc_row_multiindex_dataframe import PandasLo 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_lt_scalar_float import PandasLtScalarFloat +from .modules.pandas_wrapper.pandas_lt_scalar_int import PandasLtScalarInt from .modules.pandas_wrapper.pandas_max import PandasMax from .modules.pandas_wrapper.pandas_mean import PandasMean from .modules.pandas_wrapper.pandas_median import PandasMedian @@ -115,6 +128,8 @@ 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_ne_scalar_float import PandasNeScalarFloat +from .modules.pandas_wrapper.pandas_ne_scalar_int import PandasNeScalarInt 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 @@ -125,6 +140,7 @@ from .modules.pandas_wrapper.pandas_rename_advanced import PandasRenameAdvanced from .modules.pandas_wrapper.pandas_replace import PandasReplace from .modules.pandas_wrapper.pandas_save_csv import PandasSaveCSV from .modules.pandas_wrapper.pandas_save_json import PandasSaveJSON +from .modules.pandas_wrapper.pandas_select_column_as_series import PandasSelectColumnAsSeries from .modules.pandas_wrapper.pandas_select_columns import PandasSelectColumns from .modules.pandas_wrapper.pandas_select_rows import PandasSelectRows from .modules.pandas_wrapper.pandas_series_to_dataframe import PandasSeriesToDataFrame @@ -300,6 +316,7 @@ NODE_CLASS_MAPPINGS: Dict[str, Type[T]] = { "PandasAtSetInt": PandasAtSetInt, "PandasAtSetString": PandasAtSetString, "PandasAtString": PandasAtString, + "PandasBooleanIndex": PandasBooleanIndex, "PandasColumns": PandasColumns, "PandasCorr": PandasCorr, "PandasCos": PandasCos, @@ -312,6 +329,8 @@ NODE_CLASS_MAPPINGS: Dict[str, Type[T]] = { "PandasCreateFromNumpy": PandasCreateFromNumpy, "PandasCreateFromTensor": PandasCreateFromTensor, "PandasCreateSeriesFromDict": PandasCreateSeriesFromDict, + "PandasCreateSeriesFromList": PandasCreateSeriesFromList, + "PandasCreateSeriesFromListIndexList": PandasCreateSeriesFromListIndexList, "PandasCreateWithIndex": PandasCreateWithIndex, "PandasCrosstab": PandasCrosstab, "PandasCummax": PandasCummax, @@ -325,13 +344,19 @@ NODE_CLASS_MAPPINGS: Dict[str, Type[T]] = { "PandasDropDuplicates": PandasDropDuplicates, "PandasDropNA": PandasDropNA, "PandasEq": PandasEq, + "PandasEqScalarFloat": PandasEqScalarFloat, + "PandasEqScalarInt": PandasEqScalarInt, "PandasExp": PandasExp, "PandasFeatureSplitToNumpy": PandasFeatureSplitToNumpy, "PandasFillNAScalarFloat": PandasFillNAScalarFloat, "PandasFillNAScalarInt": PandasFillNAScalarInt, "PandasGe": PandasGe, + "PandasGeScalarFloat": PandasGeScalarFloat, + "PandasGeScalarInt": PandasGeScalarInt, "PandasGroupBy": PandasGroupBy, "PandasGt": PandasGt, + "PandasGtScalarFloat": PandasGtScalarFloat, + "PandasGtScalarInt": PandasGtScalarInt, "PandasHead": PandasHead, "PandasHorizontalConcat": PandasHorizontalConcat, "PandasHorizontalSplit": PandasHorizontalSplit, @@ -352,6 +377,8 @@ NODE_CLASS_MAPPINGS: Dict[str, Type[T]] = { "PandasJoin": PandasJoin, "PandasKurtosis": PandasKurtosis, "PandasLe": PandasLe, + "PandasLeScalarFloat": PandasLeScalarFloat, + "PandasLeScalarInt": PandasLeScalarInt, "PandasLoadCSV": PandasLoadCSV, "PandasLoadCSVWithEncoding": PandasLoadCSVWithEncoding, "PandasLoadCSVWithIndex": PandasLoadCSVWithIndex, @@ -363,6 +390,8 @@ NODE_CLASS_MAPPINGS: Dict[str, Type[T]] = { "PandasLocRowSeries": PandasLocRowSeries, "PandasLog": PandasLog, "PandasLt": PandasLt, + "PandasLtScalarFloat": PandasLtScalarFloat, + "PandasLtScalarInt": PandasLtScalarInt, "PandasMax": PandasMax, "PandasMean": PandasMean, "PandasMedian": PandasMedian, @@ -374,6 +403,8 @@ NODE_CLASS_MAPPINGS: Dict[str, Type[T]] = { "PandasMulScalarInt": PandasMulScalarInt, "PandasMulSeries": PandasMulSeries, "PandasNe": PandasNe, + "PandasNeScalarFloat": PandasNeScalarFloat, + "PandasNeScalarInt": PandasNeScalarInt, "PandasPivot": PandasPivot, "PandasPow": PandasPow, "PandasPowScalarFloat": PandasPowScalarFloat, @@ -384,6 +415,7 @@ NODE_CLASS_MAPPINGS: Dict[str, Type[T]] = { "PandasReplace": PandasReplace, "PandasSaveCSV": PandasSaveCSV, "PandasSaveJSON": PandasSaveJSON, + "PandasSelectColumnAsSeries": PandasSelectColumnAsSeries, "PandasSelectColumns": PandasSelectColumns, "PandasSelectRows": PandasSelectRows, "PandasSeriesToDataFrame": PandasSeriesToDataFrame, @@ -570,6 +602,7 @@ NODE_DISPLAY_NAME_MAPPINGS: Dict[str, str] = { "PandasAtSetInt": "Pandas At Set Int", "PandasAtSetString": "Pandas At Set String", "PandasAtString": "Pandas At String", + "PandasBooleanIndex": "Pandas Boolean Index", "PandasColumns": "Pandas Columns", "PandasCorr": "Pandas Corr", "PandasCos": "Pandas Cos", @@ -582,6 +615,8 @@ NODE_DISPLAY_NAME_MAPPINGS: Dict[str, str] = { "PandasCreateFromNumpy": "Pandas Create From Numpy", "PandasCreateFromTensor": "Pandas Create From Tensor", "PandasCreateSeriesFromDict": "Pandas Create Series From Dict", + "PandasCreateSeriesFromList": "Pandas Create Series From List", + "PandasCreateSeriesFromListIndexList": "Pandas Create Series From List Index List", "PandasCreateWithIndex": "Pandas Create With Index", "PandasCrosstab": "Pandas Crosstab", "PandasCummax": "Pandas Cummax", @@ -595,13 +630,19 @@ NODE_DISPLAY_NAME_MAPPINGS: Dict[str, str] = { "PandasDropDuplicates": "Pandas Drop Duplicates", "PandasDropNA": "Pandas Drop NA", "PandasEq": "Pandas Eq", + "PandasEqScalarFloat": "Pandas Eq Scalar Float", + "PandasEqScalarInt": "Pandas Eq Scalar Int", "PandasExp": "Pandas Exp", "PandasFeatureSplitToNumpy": "Pandas Feature Split To Numpy", "PandasFillNAScalarFloat": "Pandas Fill NA Scalar Float", "PandasFillNAScalarInt": "Pandas Fill NA Scalar Int", "PandasGe": "Pandas Ge", + "PandasGeScalarFloat": "Pandas Ge Scalar Float", + "PandasGeScalarInt": "Pandas Ge Scalar Int", "PandasGroupBy": "Pandas Group By", "PandasGt": "Pandas Gt", + "PandasGtScalarFloat": "Pandas Gt Scalar Float", + "PandasGtScalarInt": "Pandas Gt Scalar Int", "PandasHead": "Pandas Head", "PandasHorizontalConcat": "Pandas Horizontal Concat", "PandasHorizontalSplit": "Pandas Horizontal Split", @@ -622,6 +663,8 @@ NODE_DISPLAY_NAME_MAPPINGS: Dict[str, str] = { "PandasJoin": "Pandas Join", "PandasKurtosis": "Pandas Kurtosis", "PandasLe": "Pandas Le", + "PandasLeScalarFloat": "Pandas Le Scalar Float", + "PandasLeScalarInt": "Pandas Le Scalar Int", "PandasLoadCSV": "Pandas Load CSV", "PandasLoadCSVWithEncoding": "Pandas Load CSV With Encoding", "PandasLoadCSVWithIndex": "Pandas Load CSV With Index", @@ -633,6 +676,8 @@ NODE_DISPLAY_NAME_MAPPINGS: Dict[str, str] = { "PandasLocRowSeries": "Pandas Loc Row Series", "PandasLog": "Pandas Log", "PandasLt": "Pandas Lt", + "PandasLtScalarFloat": "Pandas Lt Scalar Float", + "PandasLtScalarInt": "Pandas Lt Scalar Int", "PandasMax": "Pandas Max", "PandasMean": "Pandas Mean", "PandasMedian": "Pandas Median", @@ -644,6 +689,8 @@ NODE_DISPLAY_NAME_MAPPINGS: Dict[str, str] = { "PandasMulScalarInt": "Pandas Mul Scalar Int", "PandasMulSeries": "Pandas Mul Series", "PandasNe": "Pandas Ne", + "PandasNeScalarFloat": "Pandas Ne Scalar Float", + "PandasNeScalarInt": "Pandas Ne Scalar Int", "PandasPivot": "Pandas Pivot", "PandasPow": "Pandas Pow", "PandasPowScalarFloat": "Pandas Pow Scalar Float", @@ -654,6 +701,7 @@ NODE_DISPLAY_NAME_MAPPINGS: Dict[str, str] = { "PandasReplace": "Pandas Replace", "PandasSaveCSV": "Pandas Save CSV", "PandasSaveJSON": "Pandas Save JSON", + "PandasSelectColumnAsSeries": "Pandas Select Column As Series", "PandasSelectColumns": "Pandas Select Columns", "PandasSelectRows": "Pandas Select Rows", "PandasSeriesToDataFrame": "Pandas Series To DataFrame", diff --git a/docs/reference/node_reference.md b/docs/reference/node_reference.md index 5920c60..c7a1f0b 100644 --- a/docs/reference/node_reference.md +++ b/docs/reference/node_reference.md @@ -54,6 +54,7 @@ | [Pandas At Float](pandas_at_float.md) | Selects a cell from a pandas DataFrame and output as a Python float. | | [Pandas At Int](pandas_at_int.md) | Selects a cell from a pandas DataFrame and output as a Python int. | | [Pandas At String](pandas_at_string.md) | Selects a cell from a pandas DataFrame and output as a string. | +| [Pandas Boolean Index](pandas_boolean_index.md) | Selects rows from a pandas DataFrame based on the boolean index in the Series. | | [Pandas Head](pandas_head.md) | Retrieves the first few rows of a pandas DataFrame. | | [Pandas Iat Datetime](pandas_iat_datetime.md) | Selects a cell from a pandas DataFrame and output as a Python datetime.datetime data. | | [Pandas Iat Float](pandas_iat_float.md) | Selects a cell from a pandas DataFrame and output as a Python float. | @@ -65,6 +66,7 @@ | [Pandas Loc Cell String](pandas_loc_cell_string.md) | Selects a cell from a pandas DataFrame and output as a string. | | [Pandas Loc Row MultiIndex DataFrame](pandas_loc_row_multiindex_dataframe.md) | Selects a row or rows from a pandas DataFrame with MultiIndex and output as a DataFrame. | | [Pandas Loc Row Series](pandas_loc_row_series.md) | Selects a row from a pandas DataFrame and output as a Series. | +| [Pandas Select Column As Series](pandas_select_column_as_series.md) | Selects specific column as Series from a pandas DataFrame. | | [Pandas Select Columns](pandas_select_columns.md) | Selects specific columns from a pandas DataFrame. | | [Pandas Select Rows](pandas_select_rows.md) | Selects specific rows from a pandas DataFrame based on a condition. This node internally calls DataFrame.query(). | | [Pandas Xs](pandas_xs.md) | Selects a subset of a Pandas DataFrame using specified index labels or positions. | @@ -114,6 +116,8 @@ | [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. | | [Pandas Create Series From Dict](pandas_create_series_from_dict.md) | Creates a Pandas Series from a Python dictionary. | +| [Pandas Create Series From List](pandas_create_series_from_list.md) | Creates a Pandas Series from a Python list. | +| [Pandas Create Series From List Index List](pandas_create_series_from_list_index_list.md) | Creates a Pandas Series from a Python list of cell values and a list for index. | | [Pandas Create With Index](pandas_create_with_index.md) | Creates a pandas DataFrame using values entered in the text field. Input data is assumed to have an index. | | [Pandas Load CSV](pandas_load_csv.md) | Loads CSV files into a pandas DataFrame. | | [Pandas Load CSV With Encoding](pandas_load_csv_with_encoding.md) | Loads CSV files into a pandas DataFrame. | @@ -128,11 +132,23 @@ | 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 Eq Scalar Float](pandas_eq_scalar_float.md) | Determines whether each element in the pandas DataFrame is equal to the float. | +| [Pandas Eq Scalar Int](pandas_eq_scalar_int.md) | Determines whether each element in the pandas DataFrame is equal to the float. | | [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 Ge Scalar Float](pandas_ge_scalar_float.md) | Determines whether each element in the pandas DataFrame is greater than or equal to the float. | +| [Pandas Ge Scalar Int](pandas_ge_scalar_int.md) | Determines whether each element in the pandas DataFrame is greater than or equal to the int. | | [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 Gt Scalar Float](pandas_gt_scalar_float.md) | Determines whether each element in the first pandas DataFrame is greater than the corresponding element in the second DataFrame. | +| [Pandas Gt Scalar Int](pandas_gt_scalar_int.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 Le Scalar Float](pandas_le_scalar_float.md) | Determines whether each element in the pandas DataFrame is less than or equal to the float. | +| [Pandas Le Scalar Int](pandas_le_scalar_int.md) | Determines whether each element in the pandas DataFrame is less than or equal to the int. | | [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 Lt Scalar Float](pandas_lt_scalar_float.md) | Determines whether each element in the pandas DataFrame is less than the float. | +| [Pandas Lt Scalar Int](pandas_lt_scalar_int.md) | Determines whether each element in the pandas DataFrame is less than the int. | | [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. | +| [Pandas Ne Scalar Float](pandas_ne_scalar_float.md) | Determines whether each element in the pandas DataFrame is not equal to the float. | +| [Pandas Ne Scalar Int](pandas_ne_scalar_int.md) | Determines whether each element in the pandas DataFrame is not equal to the int. | ## Math | Node | Description | | --- | --- | diff --git a/docs/reference/pandas_boolean_index.md b/docs/reference/pandas_boolean_index.md new file mode 100644 index 0000000..0868428 --- /dev/null +++ b/docs/reference/pandas_boolean_index.md @@ -0,0 +1,18 @@ +# Pandas Boolean Index +Selects rows from a pandas DataFrame based on the boolean index in the Series. + +## Input +| Name | Data type | +|---|---| +| dataframe | DataFrame | +| boolean_index_series | Series | + +## Output +| Data type | +|---| +| DataFrame | + +
+Category: Data subset selection + +ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pandas_create_series_from_list.md b/docs/reference/pandas_create_series_from_list.md new file mode 100644 index 0000000..4320e3a --- /dev/null +++ b/docs/reference/pandas_create_series_from_list.md @@ -0,0 +1,17 @@ +# Pandas Create Series From List +Creates a Pandas Series from a Python list. + +## Input +| Name | Data type | +|---|---| +| data | Pylist | + +## Output +| Data type | +|---| +| Series | + +
+Category: IO + +ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pandas_create_series_from_list_index_list.md b/docs/reference/pandas_create_series_from_list_index_list.md new file mode 100644 index 0000000..84eef4d --- /dev/null +++ b/docs/reference/pandas_create_series_from_list_index_list.md @@ -0,0 +1,18 @@ +# Pandas Create Series From List Index List +Creates a Pandas Series from a Python list of cell values and a list for index. + +## Input +| Name | Data type | +|---|---| +| data | Pylist | +| index | Pylist | + +## Output +| Data type | +|---| +| Series | + +
+Category: IO + +ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pandas_eq_scalar_float.md b/docs/reference/pandas_eq_scalar_float.md new file mode 100644 index 0000000..e6a18c8 --- /dev/null +++ b/docs/reference/pandas_eq_scalar_float.md @@ -0,0 +1,18 @@ +# Pandas Eq Scalar Float +Determines whether each element in the pandas DataFrame is equal to the float. + +## Input +| Name | Data type | +|---|---| +| dataframe | DataFrame | +| number | Float | + +## Output +| Data type | +|---| +| DataFrame | + +
+Category: Logical operations + +ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pandas_eq_scalar_int.md b/docs/reference/pandas_eq_scalar_int.md new file mode 100644 index 0000000..ce99f31 --- /dev/null +++ b/docs/reference/pandas_eq_scalar_int.md @@ -0,0 +1,18 @@ +# Pandas Eq Scalar Int +Determines whether each element in the pandas DataFrame is equal to the float. + +## Input +| Name | Data type | +|---|---| +| dataframe | DataFrame | +| number | Int | + +## Output +| Data type | +|---| +| DataFrame | + +
+Category: Logical operations + +ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pandas_ge_scalar_float.md b/docs/reference/pandas_ge_scalar_float.md new file mode 100644 index 0000000..d98c2a3 --- /dev/null +++ b/docs/reference/pandas_ge_scalar_float.md @@ -0,0 +1,18 @@ +# Pandas Ge Scalar Float +Determines whether each element in the pandas DataFrame is greater than or equal to the float. + +## Input +| Name | Data type | +|---|---| +| dataframe | DataFrame | +| number | Float | + +## Output +| Data type | +|---| +| DataFrame | + +
+Category: Logical operations + +ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pandas_ge_scalar_int.md b/docs/reference/pandas_ge_scalar_int.md new file mode 100644 index 0000000..4582ed5 --- /dev/null +++ b/docs/reference/pandas_ge_scalar_int.md @@ -0,0 +1,18 @@ +# Pandas Ge Scalar Int +Determines whether each element in the pandas DataFrame is greater than or equal to the int. + +## Input +| Name | Data type | +|---|---| +| dataframe | DataFrame | +| number | Int | + +## Output +| Data type | +|---| +| DataFrame | + +
+Category: Logical operations + +ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pandas_gt_scalar_float.md b/docs/reference/pandas_gt_scalar_float.md new file mode 100644 index 0000000..b7150e0 --- /dev/null +++ b/docs/reference/pandas_gt_scalar_float.md @@ -0,0 +1,18 @@ +# Pandas Gt Scalar Float +Determines whether each element in the first pandas DataFrame is greater than the corresponding element in the second DataFrame. + +## Input +| Name | Data type | +|---|---| +| dataframe | DataFrame | +| number | Float | + +## Output +| Data type | +|---| +| DataFrame | + +
+Category: Logical operations + +ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pandas_gt_scalar_int.md b/docs/reference/pandas_gt_scalar_int.md new file mode 100644 index 0000000..aad3d30 --- /dev/null +++ b/docs/reference/pandas_gt_scalar_int.md @@ -0,0 +1,18 @@ +# Pandas Gt Scalar Int +Determines whether each element in the first pandas DataFrame is greater than the corresponding element in the second DataFrame. + +## Input +| Name | Data type | +|---|---| +| dataframe | DataFrame | +| number | Int | + +## Output +| Data type | +|---| +| DataFrame | + +
+Category: Logical operations + +ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pandas_le_scalar_float.md b/docs/reference/pandas_le_scalar_float.md new file mode 100644 index 0000000..edd6144 --- /dev/null +++ b/docs/reference/pandas_le_scalar_float.md @@ -0,0 +1,18 @@ +# Pandas Le Scalar Float +Determines whether each element in the pandas DataFrame is less than or equal to the float. + +## Input +| Name | Data type | +|---|---| +| dataframe | DataFrame | +| number | Float | + +## Output +| Data type | +|---| +| DataFrame | + +
+Category: Logical operations + +ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pandas_le_scalar_int.md b/docs/reference/pandas_le_scalar_int.md new file mode 100644 index 0000000..f831080 --- /dev/null +++ b/docs/reference/pandas_le_scalar_int.md @@ -0,0 +1,18 @@ +# Pandas Le Scalar Int +Determines whether each element in the pandas DataFrame is less than or equal to the int. + +## Input +| Name | Data type | +|---|---| +| dataframe | DataFrame | +| number | Int | + +## Output +| Data type | +|---| +| DataFrame | + +
+Category: Logical operations + +ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pandas_lt_scalar_float.md b/docs/reference/pandas_lt_scalar_float.md new file mode 100644 index 0000000..ab2d3d0 --- /dev/null +++ b/docs/reference/pandas_lt_scalar_float.md @@ -0,0 +1,18 @@ +# Pandas Lt Scalar Float +Determines whether each element in the pandas DataFrame is less than the float. + +## Input +| Name | Data type | +|---|---| +| dataframe | DataFrame | +| number | Float | + +## Output +| Data type | +|---| +| DataFrame | + +
+Category: Logical operations + +ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pandas_lt_scalar_int.md b/docs/reference/pandas_lt_scalar_int.md new file mode 100644 index 0000000..dcf0c01 --- /dev/null +++ b/docs/reference/pandas_lt_scalar_int.md @@ -0,0 +1,18 @@ +# Pandas Lt Scalar Int +Determines whether each element in the pandas DataFrame is less than the int. + +## Input +| Name | Data type | +|---|---| +| dataframe | DataFrame | +| number | Int | + +## Output +| Data type | +|---| +| DataFrame | + +
+Category: Logical operations + +ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pandas_ne_scalar_float.md b/docs/reference/pandas_ne_scalar_float.md new file mode 100644 index 0000000..403657b --- /dev/null +++ b/docs/reference/pandas_ne_scalar_float.md @@ -0,0 +1,18 @@ +# Pandas Ne Scalar Float +Determines whether each element in the pandas DataFrame is not equal to the float. + +## Input +| Name | Data type | +|---|---| +| dataframe | DataFrame | +| number | Float | + +## Output +| Data type | +|---| +| DataFrame | + +
+Category: Logical operations + +ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pandas_ne_scalar_int.md b/docs/reference/pandas_ne_scalar_int.md new file mode 100644 index 0000000..6e59edb --- /dev/null +++ b/docs/reference/pandas_ne_scalar_int.md @@ -0,0 +1,18 @@ +# Pandas Ne Scalar Int +Determines whether each element in the pandas DataFrame is not equal to the int. + +## Input +| Name | Data type | +|---|---| +| dataframe | DataFrame | +| number | Int | + +## Output +| Data type | +|---| +| DataFrame | + +
+Category: Logical operations + +ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pandas_select_column_as_series.md b/docs/reference/pandas_select_column_as_series.md new file mode 100644 index 0000000..999fbe7 --- /dev/null +++ b/docs/reference/pandas_select_column_as_series.md @@ -0,0 +1,18 @@ +# Pandas Select Column As Series +Selects specific column as Series from a pandas DataFrame. + +## Input +| Name | Data type | +|---|---| +| dataframe | DataFrame | +| column_name | String | + +## Output +| Data type | +|---| +| Series | + +
+Category: Data subset selection + +ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/modules/cda/py_string_to_list.py b/modules/cda/py_string_to_list.py index 740d3c8..43f43fd 100644 --- a/modules/cda/py_string_to_list.py +++ b/modules/cda/py_string_to_list.py @@ -1,4 +1,4 @@ -from typing import Any, List +from typing import Any, Dict import ast class PyStringToList: @@ -9,12 +9,12 @@ class PyStringToList: """ @classmethod - def INPUT_TYPES(cls) -> List[str]: + def INPUT_TYPES(cls) -> Dict[str, Any]: """ Defines the input types for the `create` function. Returns: - List[str, Any]: A list specifying required input types. + Dict[str, Any]: A list specifying required input types. """ return { "required": { diff --git a/modules/pandas_wrapper/pandas_boolean_index.py b/modules/pandas_wrapper/pandas_boolean_index.py new file mode 100644 index 0000000..9ec8bcd --- /dev/null +++ b/modules/pandas_wrapper/pandas_boolean_index.py @@ -0,0 +1,45 @@ +from typing import Any, Dict +import pandas as pd + +class PandasBooleanIndex: + """ + Selects rows from a pandas DataFrame based on the boolean index in the Series. + + category: Data subset selection + """ + + @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": { + "dataframe": ("DATAFRAME", {}), + "boolean_index_series": ("PDSERIES", {}) + } + } + + RETURN_TYPES: tuple = ("DATAFRAME",) + FUNCTION: str = "f" + CATEGORY: str = "Data Analysis" + + def f(self, dataframe: pd.DataFrame, boolean_index_series: pd.Series) -> tuple: + """ + Selects rows from a pandas DataFrame based on the boolean index in the Series. + + Args: + dataframe (DataFrame): The DataFrame. + boolean_index_series: (pd.Series): The Series containing boolean index. + + Returns: + tuple: A tuple containing the filtered DataFrame. + """ + if not isinstance(boolean_index_series, pd.Series): + raise ValueError("boolean_index_series is not a Series.") + + df2 = dataframe[boolean_index_series] + return (df2,) diff --git a/modules/pandas_wrapper/pandas_create_series_from_list.py b/modules/pandas_wrapper/pandas_create_series_from_list.py new file mode 100644 index 0000000..3f3a077 --- /dev/null +++ b/modules/pandas_wrapper/pandas_create_series_from_list.py @@ -0,0 +1,49 @@ +from typing import List, Any, Tuple, Dict +import pandas as pd + + +class PandasCreateSeriesFromList: + """ + Creates a Pandas Series from a Python list. + + category: IO + """ + @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": { + "data": ("PYLIST", {}), + } + } + + RETURN_TYPES: tuple = ("PDSERIES",) + FUNCTION: str = "f" + CATEGORY: str = "Data Analysis" + + def f(self, data: List[Any]) -> Tuple[pd.Series]: + """ + Creates a Pandas Series from a Python list. + + Args: + data (List[Any]): A list with cell values. + + Returns: + Tuple[pd.Series]: A tuple containing a Pandas Series. + + Raises: + ValueError: If the data is not a list. + """ + if not isinstance(data, list): + raise ValueError("Input must be a list.") + + if len(data) == 0: + return (pd.Series(),) + else: + return (pd.Series(data),) + diff --git a/modules/pandas_wrapper/pandas_create_series_from_list_index_list.py b/modules/pandas_wrapper/pandas_create_series_from_list_index_list.py new file mode 100644 index 0000000..64b0fb4 --- /dev/null +++ b/modules/pandas_wrapper/pandas_create_series_from_list_index_list.py @@ -0,0 +1,51 @@ +from typing import List, Any, Tuple, Dict +import pandas as pd + + +class PandasCreateSeriesFromListIndexList: + """ + Creates a Pandas Series from a Python list of cell values and a list for index. + + category: IO + """ + @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": { + "data": ("PYLIST", {}), + "index": ("PYLIST", {}) + } + } + + RETURN_TYPES: tuple = ("PDSERIES",) + FUNCTION: str = "f" + CATEGORY: str = "Data Analysis" + + def f(self, data: List[Any], index: List[Any]) -> Tuple[pd.Series]: + """ + Creates a Pandas Series from a Python list of cell values and a list for index. + + Args: + data (List[Any]): A list with cell values. + index (List): A Python list containing index. + + Returns: + Tuple[pd.Series]: A tuple containing a Pandas Series. + + Raises: + ValueError: If the data is not a list. + """ + if not isinstance(data, list): + raise ValueError("Input must be a list.") + + if len(data) == 0: + return (pd.Series(),) + else: + return (pd.Series(data, index=index),) + diff --git a/modules/pandas_wrapper/pandas_eq_scalar_float.py b/modules/pandas_wrapper/pandas_eq_scalar_float.py new file mode 100644 index 0000000..4e2fafd --- /dev/null +++ b/modules/pandas_wrapper/pandas_eq_scalar_float.py @@ -0,0 +1,43 @@ +from typing import Any, Dict +import pandas as pd + + +class PandasEqScalarFloat: + """ + Determines whether each element in the pandas DataFrame is equal to the float. + + 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": { + "dataframe": ("DATAFRAME", {}), + "number": ("FLOAT", {"default": 0, "min": -2**63, "max": 2**63, "step": 0.00000001}) + } + } + + RETURN_TYPES: tuple = ("DATAFRAME",) + FUNCTION: str = "f" + CATEGORY: str = "Data Analysis" + + def f(self, dataframe: pd.DataFrame, number: float) -> tuple: + """ + Determines whether each element in the pandas DataFrame is equal to the float. + + Args: + dataframe (DataFrame): The DataFrame. + number (float): The number. + + Returns: + tuple: A tuple containing the DataFrame containing the result of operation. + """ + df_out = dataframe.eq(number) + return (df_out,) diff --git a/modules/pandas_wrapper/pandas_eq_scalar_int.py b/modules/pandas_wrapper/pandas_eq_scalar_int.py new file mode 100644 index 0000000..011dbe4 --- /dev/null +++ b/modules/pandas_wrapper/pandas_eq_scalar_int.py @@ -0,0 +1,43 @@ +from typing import Any, Dict +import pandas as pd + + +class PandasEqScalarInt: + """ + Determines whether each element in the pandas DataFrame is equal to the float. + + 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": { + "dataframe": ("DATAFRAME", {}), + "number": ("INT", {"default": 0, "min": -2**31, "max": 2**31}) + } + } + + RETURN_TYPES: tuple = ("DATAFRAME",) + FUNCTION: str = "f" + CATEGORY: str = "Data Analysis" + + def f(self, dataframe: pd.DataFrame, number: float) -> tuple: + """ + Determines whether each element in the pandas DataFrame is equal to the float. + + Args: + dataframe (DataFrame): The DataFrame. + number (float): The number. + + Returns: + tuple: A tuple containing the DataFrame containing the result of operation. + """ + df_out = dataframe.eq(number) + return (df_out,) diff --git a/modules/pandas_wrapper/pandas_ge_scalar_float.py b/modules/pandas_wrapper/pandas_ge_scalar_float.py new file mode 100644 index 0000000..1a83e02 --- /dev/null +++ b/modules/pandas_wrapper/pandas_ge_scalar_float.py @@ -0,0 +1,43 @@ +from typing import Any, Dict +import pandas as pd + + +class PandasGeScalarFloat: + """ + Determines whether each element in the pandas DataFrame is greater than or equal to the float. + + 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": { + "dataframe": ("DATAFRAME", {}), + "number": ("FLOAT", {"default": 0, "min": -2**63, "max": 2**63, "step": 0.00000001}) + } + } + + RETURN_TYPES: tuple = ("DATAFRAME",) + FUNCTION: str = "f" + CATEGORY: str = "Data Analysis" + + def f(self, dataframe: pd.DataFrame, number: float) -> tuple: + """ + Determines whether each element in the pandas DataFrame is greater than or equal to the float. + + Args: + dataframe (DataFrame): The DataFrame. + number (float): The number. + + Returns: + tuple: A tuple containing the DataFrame containing the result of operation. + """ + df_out = dataframe.ge(number) + return (df_out,) diff --git a/modules/pandas_wrapper/pandas_ge_scalar_int.py b/modules/pandas_wrapper/pandas_ge_scalar_int.py new file mode 100644 index 0000000..abb5818 --- /dev/null +++ b/modules/pandas_wrapper/pandas_ge_scalar_int.py @@ -0,0 +1,43 @@ +from typing import Any, Dict +import pandas as pd + + +class PandasGeScalarInt: + """ + Determines whether each element in the pandas DataFrame is greater than or equal to the int. + + 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": { + "dataframe": ("DATAFRAME", {}), + "number": ("INT", {"default": 0, "min": -2**31, "max": 2**31}) + } + } + + RETURN_TYPES: tuple = ("DATAFRAME",) + FUNCTION: str = "f" + CATEGORY: str = "Data Analysis" + + def f(self, dataframe: pd.DataFrame, number: int) -> tuple: + """ + Determines whether each element in the pandas DataFrame is greater than or equal to the int. + + Args: + dataframe (DataFrame): The DataFrame. + number (int): The number. + + Returns: + tuple: A tuple containing the DataFrame containing the result of operation. + """ + df_out = dataframe.ge(number) + return (df_out,) diff --git a/modules/pandas_wrapper/pandas_gt_scalar_float.py b/modules/pandas_wrapper/pandas_gt_scalar_float.py new file mode 100644 index 0000000..7a677e9 --- /dev/null +++ b/modules/pandas_wrapper/pandas_gt_scalar_float.py @@ -0,0 +1,43 @@ +from typing import Any, Dict +import pandas as pd + + +class PandasGtScalarFloat: + """ + 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": { + "dataframe": ("DATAFRAME", {}), + "number": ("FLOAT", {"default": 0, "min": -2**63, "max": 2**63, "step": 0.00000001}) + } + } + + RETURN_TYPES: tuple = ("DATAFRAME",) + FUNCTION: str = "f" + CATEGORY: str = "Data Analysis" + + def f(self, dataframe: pd.DataFrame, number: float) -> tuple: + """ + Determines whether each element in the pandas DataFrame is greater than or equal to the float. + + Args: + dataframe (DataFrame): The DataFrame. + number (float): The number. + + Returns: + tuple: A tuple containing the DataFrame containing the result of operation. + """ + df_out = dataframe.gt(number) + return (df_out,) diff --git a/modules/pandas_wrapper/pandas_gt_scalar_int.py b/modules/pandas_wrapper/pandas_gt_scalar_int.py new file mode 100644 index 0000000..56df1ad --- /dev/null +++ b/modules/pandas_wrapper/pandas_gt_scalar_int.py @@ -0,0 +1,44 @@ +from typing import Any, Dict +import pandas as pd + + +class PandasGtScalarInt: + """ + 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": { + "dataframe": ("DATAFRAME", {}), + "number": ("INT", {"default": 0, "min": -2**31, "max": 2**31} +) + } + } + + RETURN_TYPES: tuple = ("DATAFRAME",) + FUNCTION: str = "f" + CATEGORY: str = "Data Analysis" + + def f(self, dataframe: pd.DataFrame, number: int) -> tuple: + """ + Determines whether each element in the pandas DataFrame is greater than or equal to the int. + + Args: + dataframe (DataFrame): The DataFrame. + number (int): The number. + + Returns: + tuple: A tuple containing the DataFrame containing the result of operation. + """ + df_out = dataframe.gt(number) + return (df_out,) diff --git a/modules/pandas_wrapper/pandas_le_scalar_float.py b/modules/pandas_wrapper/pandas_le_scalar_float.py new file mode 100644 index 0000000..5dc6505 --- /dev/null +++ b/modules/pandas_wrapper/pandas_le_scalar_float.py @@ -0,0 +1,44 @@ +from typing import Any, Dict +import pandas as pd + + +class PandasLeScalarFloat: + """ + Determines whether each element in the pandas DataFrame is less than or equal to the float. + + 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": { + "dataframe": ("DATAFRAME", {}), + "number": ("FLOAT", {"default": 0, "min": -2**63, "max": 2**63, "step": 0.00000001}) + + } + } + + RETURN_TYPES: tuple = ("DATAFRAME",) + FUNCTION: str = "f" + CATEGORY: str = "Data Analysis" + + def f(self, dataframe: pd.DataFrame, number: float) -> tuple: + """ + Determines whether each element in the pandas DataFrame is less than or equal to the float. + + Args: + dataframe (DataFrame): The DataFrame. + number (float): The number. + + Returns: + tuple: A tuple containing the DataFrame containing the result of operation. + """ + df_out = dataframe.le(number) + return (df_out,) diff --git a/modules/pandas_wrapper/pandas_le_scalar_int.py b/modules/pandas_wrapper/pandas_le_scalar_int.py new file mode 100644 index 0000000..0170433 --- /dev/null +++ b/modules/pandas_wrapper/pandas_le_scalar_int.py @@ -0,0 +1,45 @@ +from typing import Any, Dict +import pandas as pd + + +class PandasLeScalarInt: + """ + Determines whether each element in the pandas DataFrame is less than or equal to the int. + + 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": { + "dataframe": ("DATAFRAME", {}), + "number": ("INT", {"default": 0, "min": -2**31, "max": 2**31} +) + + } + } + + RETURN_TYPES: tuple = ("DATAFRAME",) + FUNCTION: str = "f" + CATEGORY: str = "Data Analysis" + + def f(self, dataframe: pd.DataFrame, number: int) -> tuple: + """ + Determines whether each element in the pandas DataFrame is less than or equal to the int. + + Args: + dataframe (DataFrame): The DataFrame. + number (int): The number. + + Returns: + tuple: A tuple containing the DataFrame containing the result of operation. + """ + df_out = dataframe.le(number) + return (df_out,) diff --git a/modules/pandas_wrapper/pandas_lt_scalar_float.py b/modules/pandas_wrapper/pandas_lt_scalar_float.py new file mode 100644 index 0000000..39969f4 --- /dev/null +++ b/modules/pandas_wrapper/pandas_lt_scalar_float.py @@ -0,0 +1,44 @@ +from typing import Any, Dict +import pandas as pd + + +class PandasLtScalarFloat: + """ + Determines whether each element in the pandas DataFrame is less than the float. + + 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": { + "dataframe": ("DATAFRAME", {}), + "number": ("FLOAT", {"default": 0, "min": -2**63, "max": 2**63, "step": 0.00000001}) + + } + } + + RETURN_TYPES: tuple = ("DATAFRAME",) + FUNCTION: str = "f" + CATEGORY: str = "Data Analysis" + + def f(self, dataframe: pd.DataFrame, number: float) -> tuple: + """ + Determines whether each element in the pandas DataFrame is less than the float. + + Args: + dataframe (DataFrame): The DataFrame. + number (float): The number. + + Returns: + tuple: A tuple containing the DataFrame containing the result of operation. + """ + df_out = dataframe.lt(number) + return (df_out,) diff --git a/modules/pandas_wrapper/pandas_lt_scalar_int.py b/modules/pandas_wrapper/pandas_lt_scalar_int.py new file mode 100644 index 0000000..aa7e7c0 --- /dev/null +++ b/modules/pandas_wrapper/pandas_lt_scalar_int.py @@ -0,0 +1,45 @@ +from typing import Any, Dict +import pandas as pd + + +class PandasLtScalarInt: + """ + Determines whether each element in the pandas DataFrame is less than the int. + + 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": { + "dataframe": ("DATAFRAME", {}), + "number": ("INT", {"default": 0, "min": -2**31, "max": 2**31} +) + + } + } + + RETURN_TYPES: tuple = ("DATAFRAME",) + FUNCTION: str = "f" + CATEGORY: str = "Data Analysis" + + def f(self, dataframe: pd.DataFrame, number: int) -> tuple: + """ + Determines whether each element in the pandas DataFrame is less than the int. + + Args: + dataframe (DataFrame): The DataFrame. + number (int): The number. + + Returns: + tuple: A tuple containing the DataFrame containing the result of operation. + """ + df_out = dataframe.lt(number) + return (df_out,) diff --git a/modules/pandas_wrapper/pandas_ne_scalar_float.py b/modules/pandas_wrapper/pandas_ne_scalar_float.py new file mode 100644 index 0000000..50c516a --- /dev/null +++ b/modules/pandas_wrapper/pandas_ne_scalar_float.py @@ -0,0 +1,43 @@ +from typing import Any, Dict +import pandas as pd + + +class PandasNeScalarFloat: + """ + Determines whether each element in the pandas DataFrame is not equal to the float. + + 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": { + "dataframe": ("DATAFRAME", {}), + "number": ("FLOAT", {"default": 0, "min": -2**63, "max": 2**63, "step": 0.00000001}) + } + } + + RETURN_TYPES: tuple = ("DATAFRAME",) + FUNCTION: str = "f" + CATEGORY: str = "Data Analysis" + + def f(self, dataframe: pd.DataFrame, number: float) -> tuple: + """ + Determines whether each element in the pandas DataFrame is not equal to the float. + + Args: + dataframe (DataFrame): The DataFrame. + number (float): The number. + + Returns: + tuple: A tuple containing the DataFrame containing the result of operation. + """ + df_out = dataframe.ne(number) + return (df_out,) diff --git a/modules/pandas_wrapper/pandas_ne_scalar_int.py b/modules/pandas_wrapper/pandas_ne_scalar_int.py new file mode 100644 index 0000000..6ed3702 --- /dev/null +++ b/modules/pandas_wrapper/pandas_ne_scalar_int.py @@ -0,0 +1,43 @@ +from typing import Any, Dict +import pandas as pd + + +class PandasNeScalarInt: + """ + Determines whether each element in the pandas DataFrame is not equal to the int. + + 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": { + "dataframe": ("DATAFRAME", {}), + "number": ("INT", {"default": 0, "min": -2**31, "max": 2**31} +) } + } + + RETURN_TYPES: tuple = ("DATAFRAME",) + FUNCTION: str = "f" + CATEGORY: str = "Data Analysis" + + def f(self, dataframe: pd.DataFrame, number: int) -> tuple: + """ + Determines whether each element in the pandas DataFrame is not equal to the int. + + Args: + dataframe (DataFrame): The DataFrame. + number (int): The number. + + Returns: + tuple: A tuple containing the DataFrame containing the result of operation. + """ + df_out = dataframe.ne(number) + return (df_out,) diff --git a/modules/pandas_wrapper/pandas_select_column_as_series.py b/modules/pandas_wrapper/pandas_select_column_as_series.py new file mode 100644 index 0000000..24a7e29 --- /dev/null +++ b/modules/pandas_wrapper/pandas_select_column_as_series.py @@ -0,0 +1,43 @@ +from typing import Any, Dict +import pandas as pd +from .utils import column_labels_string_to_list + +class PandasSelectColumnAsSeries: + """ + Selects specific column as Series from a pandas DataFrame. + + category: Data subset selection + """ + + @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": { + "dataframe": ("DATAFRAME", {}), + "column_name": ("STRING", {"default": ""}) + } + } + + RETURN_TYPES: tuple = ("PDSERIES",) + FUNCTION: str = "f" + CATEGORY: str = "Data Analysis" + + def f(self, dataframe: pd.DataFrame, column_name: str) -> tuple: + """ + Selects specific column as Series from a pandas DataFrame. + + Args: + dataframe (DataFrame): The DataFrame. + column_name (str): A column name to select. + + Returns: + tuple: A tuple containing the Series with selected column. + """ + series = dataframe[column_name] + return (series,) diff --git a/pyproject.toml b/pyproject.toml index b7a8c1e..593a25e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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.9" +version = "2.0.10" license = {file = "LICENSE"} [project.urls] diff --git a/tests/pandas_wrapper/pandas_boolean_index_test.py b/tests/pandas_wrapper/pandas_boolean_index_test.py new file mode 100644 index 0000000..2d465b7 --- /dev/null +++ b/tests/pandas_wrapper/pandas_boolean_index_test.py @@ -0,0 +1,76 @@ +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_boolean_index import PandasBooleanIndex + +class TestPandasBooleanIndex(unittest.TestCase): + def setUp(self): + """Set up test data.""" + self.node = PandasBooleanIndex() + self.valid_test_cases = [ + # Basic boolean indexing + ( + pd.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]}, index=["x", "y", "z"]), + pd.Series([True, False, True], index=["x", "y", "z"]), + pd.DataFrame({"a": [1, 3], "b": [4, 6]}, index=["x", "z"]) + ), + # All True case + ( + pd.DataFrame({"a": [10, 20, 30]}), + pd.Series([True, True, True]), + pd.DataFrame({"a": [10, 20, 30]}) + ), + # All False case + ( + pd.DataFrame({"a": [100, 200, 300]}), + pd.Series([False, False, False]), + pd.DataFrame({"a": []}).astype("int64") + ), + # Mixed True/False with different index labels + ( + pd.DataFrame({"a": [1.1, 2.2, 3.3]}, index=["row1", "row2", "row3"]), + pd.Series([False, True, False], index=["row1", "row2", "row3"]), + pd.DataFrame({"a": [2.2]}, index=["row2"]) + ), + ] + + self.invalid_test_cases = [ + # Series with incorrect index + ( + pd.DataFrame({"a": [1, 2, 3]}, index=["x", "y", "z"]), + pd.Series([True, False], index=["x", "y"]), # Mismatched length + ), + # Non-boolean Series + ( + pd.DataFrame({"a": [1, 2, 3]}, index=["x", "y", "z"]), + pd.Series([1, 0, 1], index=["x", "y", "z"]), # Non-boolean values + ), + # Non-Series boolean index + ( + pd.DataFrame({"a": [1, 2, 3]}, index=["x", "y", "z"]), + [True, False, True], # List instead of Series + ), + ] + + def test_boolean_indexing(self): + """Test filtering DataFrame rows based on boolean Series.""" + for dataframe, boolean_series, expected_df in self.valid_test_cases: + with self.subTest(dataframe=dataframe, boolean_series=boolean_series): + retval = self.node.f(dataframe, boolean_series)[0] + self.assertTrue(isinstance(retval, pd.DataFrame), "Expected DataFrame output.") + pd.testing.assert_frame_equal(retval, expected_df) + + def test_invalid_inputs(self): + """Test that invalid inputs raise errors.""" + for dataframe, boolean_series in self.invalid_test_cases: + with self.subTest(dataframe=dataframe, boolean_series=boolean_series): + with self.assertRaises(Exception): + self.node.f(dataframe, boolean_series) + +if __name__ == "__main__": + unittest.main() \ No newline at end of file diff --git a/tests/pandas_wrapper/pandas_create_series_from_list_index_list_test.py b/tests/pandas_wrapper/pandas_create_series_from_list_index_list_test.py new file mode 100644 index 0000000..4c52046 --- /dev/null +++ b/tests/pandas_wrapper/pandas_create_series_from_list_index_list_test.py @@ -0,0 +1,78 @@ +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_series_from_list_index_list import PandasCreateSeriesFromListIndexList + +class TestPandasCreateSeriesFromListIndexList(unittest.TestCase): + def setUp(self): + """Set up test data.""" + self.node = PandasCreateSeriesFromListIndexList() + self.valid_test_cases = [ + # Empty list + ([], [], pd.Series([])), + + # List with single values + ([12345], ["a"], pd.Series([12345], index=["a"])), + ([12345.6], [1], pd.Series([12345.6], index=[1])), + (["apple"], ["fruit"], pd.Series(["apple"], index=["fruit"])), + ([True], ["flag"], pd.Series([True], index=["flag"])), + ([None], ["null"], pd.Series([None], index=["null"])), + + # List with multiple values + ([123, 456], ["a", "b"], pd.Series([123, 456], index=["a", "b"])), + ([1.5, 3.2, -7.8], ["x", "y", "z"], pd.Series([1.5, 3.2, -7.8], index=["x", "y", "z"])), + (["Alice", 30, "NYC"], ["name", "age", "city"], pd.Series(["Alice", 30, "NYC"], index=["name", "age", "city"])), + ([False, 99, 3.14159], ["flag", "score", "pi"], pd.Series([False, 99, 3.14159], index=["flag", "score", "pi"])) + ] + + self.invalid_test_cases_value_error = [ + # Non-list inputs + (None, []), + ({}, []), + ((), []), + ("string", []), + (1234, []), + (56.78, []), + ({1, 2, 3}, []), # Set + ({"a": 1}, []), # Dict + ([1, 2], ["a"]) # Mismatched data and index length + ] + + self.invalid_test_cases_type_error = [ + ([1, 2, 3], "invalid"), # Invalid index type + ] + + def test_create_series(self): + """Test Series creation from lists with index.""" + for data, index, expected_series in self.valid_test_cases: + with self.subTest(data=data, index=index): + retval = self.node.f(data, index)[0] + + # Test if output is a Pandas Series + self.assertTrue(isinstance(retval, pd.Series), f"Expected Series, got {type(retval)}") + + # Test if Series matches expected output + pd.testing.assert_series_equal(retval, expected_series) + + def test_invalid_inputs_type_error(self): + """Test that invalid inputs raise TypeError.""" + for data, index in self.invalid_test_cases_type_error: + with self.subTest(data=data, index=index): + with self.assertRaises(TypeError): + self.node.f(data, index) + + def test_invalid_inputs_value_error(self): + """Test that invalid inputs raise ValueError.""" + for data, index in self.invalid_test_cases_value_error: + with self.subTest(data=data, index=index): + with self.assertRaises(ValueError): + self.node.f(data, index) + + +if __name__ == "__main__": + unittest.main() \ No newline at end of file diff --git a/tests/pandas_wrapper/pandas_create_series_from_list_test.py b/tests/pandas_wrapper/pandas_create_series_from_list_test.py new file mode 100644 index 0000000..04abf79 --- /dev/null +++ b/tests/pandas_wrapper/pandas_create_series_from_list_test.py @@ -0,0 +1,65 @@ +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_series_from_list import PandasCreateSeriesFromList + +class TestPandasCreateSeriesFromList(unittest.TestCase): + def setUp(self): + """Set up test data.""" + self.node = PandasCreateSeriesFromList() + self.valid_test_cases = [ + # Empty list + ([], pd.Series([])), + + # List with single values + ([12345], pd.Series([12345])), + ([12345.6], pd.Series([12345.6])), + (["apple"], pd.Series(["apple"])), + ([True], pd.Series([True])), + ([None], pd.Series([None])), + + # List with multiple values + ([123, 456], pd.Series([123, 456])), + ([1.5, 3.2, -7.8], pd.Series([1.5, 3.2, -7.8])), + (["Alice", 30, "NYC"], pd.Series(["Alice", 30, "NYC"])), + ([False, 99, 3.14159], pd.Series([False, 99, 3.14159])) + ] + + self.invalid_test_cases = [ + # Non-list inputs + None, + {}, + (), + "string", + 1234, + 56.78, + {1, 2, 3}, # Set + {"a": 1}, # Dict + ] + + def test_create_series(self): + """Test Series creation from lists.""" + for data, expected_series in self.valid_test_cases: + with self.subTest(data=data): + retval = self.node.f(data)[0] + + # Test if output is a Pandas Series + self.assertTrue(isinstance(retval, pd.Series), f"Expected Series, got {type(retval)}") + + # Test if Series matches expected output + pd.testing.assert_series_equal(retval, expected_series) + + def test_invalid_inputs(self): + """Test that invalid inputs raise ValueError.""" + for data in self.invalid_test_cases: + with self.subTest(data=data): + with self.assertRaises(ValueError): + self.node.f(data) + +if __name__ == "__main__": + unittest.main() diff --git a/tests/pandas_wrapper/pandas_eq_scalar_float_test.py b/tests/pandas_wrapper/pandas_eq_scalar_float_test.py new file mode 100644 index 0000000..dbf0e89 --- /dev/null +++ b/tests/pandas_wrapper/pandas_eq_scalar_float_test.py @@ -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_scalar_float import PandasEqScalarFloat + +class TestPandasEqScalarFloat(unittest.TestCase): + def setUp(self): + """Set up test data.""" + self.node = PandasEqScalarFloat() + self.test_cases = [ + # Test where all values are True + ( + pd.DataFrame({"a": [2.5, 3.5]}, index=["row1", "row2"]), + 2.5, + pd.DataFrame({"a": [True, False]}, index=["row1", "row2"]) + ), + # Test with mixed result + ( + pd.DataFrame({"a": [3.6, 4.9]}, index=[0, 1]), + 4.9, + pd.DataFrame({"a": [False, True]}, index=[0, 1]) + ), + # Test with integer column labels + ( + pd.DataFrame({1: [14.0, 26.0]}, index=[0, 1]), + 26.0, + pd.DataFrame({1: [False, True]}, index=[0, 1]) + ), + # Test with a False case + ( + pd.DataFrame({"a": [6.0]}, index=["row1"]), + 7.0, + pd.DataFrame({"a": [False]}, index=["row1"]) + ), + # Another False case with an integer column label + ( + pd.DataFrame({2: [7.0]}, index=["row1"]), + 7.0, + pd.DataFrame({2: [True]}, index=["row1"]) + ), + ] + + def test_eq_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() diff --git a/tests/pandas_wrapper/pandas_eq_scalar_int_test.py b/tests/pandas_wrapper/pandas_eq_scalar_int_test.py new file mode 100644 index 0000000..8211afb --- /dev/null +++ b/tests/pandas_wrapper/pandas_eq_scalar_int_test.py @@ -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_scalar_int import PandasEqScalarInt + +class TestPandasEqScalarInt(unittest.TestCase): + def setUp(self): + """Set up test data.""" + self.node = PandasEqScalarInt() + self.test_cases = [ + # Test where all values are True + ( + pd.DataFrame({"a": [2, 3.5]}, index=["row1", "row2"]), + 2, + pd.DataFrame({"a": [True, False]}, index=["row1", "row2"]) + ), + # Test with mixed result + ( + pd.DataFrame({"a": [3.6, 4]}, index=[0, 1]), + 4, + pd.DataFrame({"a": [False, True]}, index=[0, 1]) + ), + # Test with integer column labels + ( + pd.DataFrame({1: [14.0, 15]}, index=[0, 1]), + 15, + pd.DataFrame({1: [False, True]}, index=[0, 1]) + ), + # Test with a False case + ( + pd.DataFrame({"a": [6.0]}, index=["row1"]), + 7, + pd.DataFrame({"a": [False]}, index=["row1"]) + ), + # Another False case with an integer column label + ( + pd.DataFrame({2: [7]}, index=["row1"]), + 7, + pd.DataFrame({2: [True]}, index=["row1"]) + ), + ] + + def test_eq_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() diff --git a/tests/pandas_wrapper/pandas_ge_scalar_float_test.py b/tests/pandas_wrapper/pandas_ge_scalar_float_test.py new file mode 100644 index 0000000..668ac70 --- /dev/null +++ b/tests/pandas_wrapper/pandas_ge_scalar_float_test.py @@ -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_scalar_float import PandasGeScalarFloat + +class TestPandasGeScalarFloat(unittest.TestCase): + def setUp(self): + """Set up test data.""" + self.node = PandasGeScalarFloat() + self.test_cases = [ + # Test where all values are True + ( + pd.DataFrame({"a": [2.5, 3.5]}, index=["row1", "row2"]), + 2.1, + pd.DataFrame({"a": [True, True]}, index=["row1", "row2"]) + ), + # Test with mixed result + ( + pd.DataFrame({"a": [3.6, 4.9]}, index=[0, 1]), + 3.1, + pd.DataFrame({"a": [True, True]}, index=[0, 1]) + ), + # Test with integer column labels + ( + pd.DataFrame({1: [14.0, 26.0]}, index=[0, 1]), + 15.1, + pd.DataFrame({1: [False, True]}, index=[0, 1]) + ), + # Test with a False case (a < b) + ( + pd.DataFrame({"a": [6.0]}, index=["row1"]), + 7.1, + pd.DataFrame({"a": [False]}, index=["row1"]) + ), + # Another False case with an integer column label + ( + pd.DataFrame({2: [7.5]}, index=["row1"]), + 7.5, + pd.DataFrame({2: [True]}, index=["row1"]) + ), + ] + + def test_ge_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() diff --git a/tests/pandas_wrapper/pandas_ge_scalar_int_test.py b/tests/pandas_wrapper/pandas_ge_scalar_int_test.py new file mode 100644 index 0000000..946800c --- /dev/null +++ b/tests/pandas_wrapper/pandas_ge_scalar_int_test.py @@ -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_scalar_int import PandasGeScalarInt + +class TestPandasGtScalarInt(unittest.TestCase): + def setUp(self): + """Set up test data.""" + self.node = PandasGeScalarInt() + self.test_cases = [ + # Test where all values are True + ( + pd.DataFrame({"a": [2.5, 3.5]}, index=["row1", "row2"]), + 2, + pd.DataFrame({"a": [True, True]}, index=["row1", "row2"]) + ), + # Test with mixed result + ( + pd.DataFrame({"a": [3.6, 4.9]}, index=[0, 1]), + 4, + pd.DataFrame({"a": [False, True]}, index=[0, 1]) + ), + # Test with integer column labels + ( + pd.DataFrame({1: [14.0, 26.0]}, index=[0, 1]), + 15, + pd.DataFrame({1: [False, True]}, index=[0, 1]) + ), + # Test with a False case (a < b) + ( + pd.DataFrame({"a": [6.0]}, index=["row1"]), + 7, + pd.DataFrame({"a": [False]}, index=["row1"]) + ), + # Another False case with an integer column label + ( + pd.DataFrame({2: [7]}, index=["row1"]), + 7, + pd.DataFrame({2: [True]}, index=["row1"]) + ), + ] + + def test_ge_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() diff --git a/tests/pandas_wrapper/pandas_gt_scalar_float_test.py b/tests/pandas_wrapper/pandas_gt_scalar_float_test.py new file mode 100644 index 0000000..6ad1e49 --- /dev/null +++ b/tests/pandas_wrapper/pandas_gt_scalar_float_test.py @@ -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_scalar_float import PandasGtScalarFloat + +class TestPandasGtScalarFloat(unittest.TestCase): + def setUp(self): + """Set up test data.""" + self.node = PandasGtScalarFloat() + self.test_cases = [ + # Test where all values are True + ( + pd.DataFrame({"a": [2.5, 3.5]}, index=["row1", "row2"]), + 2.1, + pd.DataFrame({"a": [True, True]}, index=["row1", "row2"]) + ), + # Test with mixed result + ( + pd.DataFrame({"a": [3.6, 4.9]}, index=[0, 1]), + 4.1, + pd.DataFrame({"a": [False, True]}, index=[0, 1]) + ), + # Test with integer column labels + ( + pd.DataFrame({1: [14.0, 26.0]}, index=[0, 1]), + 15.1, + pd.DataFrame({1: [False, True]}, index=[0, 1]) + ), + # Test with a False case (a < b) + ( + pd.DataFrame({"a": [6.0]}, index=["row1"]), + 7.1, + pd.DataFrame({"a": [False]}, index=["row1"]) + ), + # Another False case with an integer column label + ( + pd.DataFrame({2: [7.5]}, index=["row1"]), + 7.5, + 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() diff --git a/tests/pandas_wrapper/pandas_gt_scalar_int_test.py b/tests/pandas_wrapper/pandas_gt_scalar_int_test.py new file mode 100644 index 0000000..977b61c --- /dev/null +++ b/tests/pandas_wrapper/pandas_gt_scalar_int_test.py @@ -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_scalar_int import PandasGtScalarInt + +class TestPandasGtScalarInt(unittest.TestCase): + def setUp(self): + """Set up test data.""" + self.node = PandasGtScalarInt() + self.test_cases = [ + # Test where all values are True + ( + pd.DataFrame({"a": [2.5, 3.5]}, index=["row1", "row2"]), + 2, + pd.DataFrame({"a": [True, True]}, index=["row1", "row2"]) + ), + # Test with mixed result + ( + pd.DataFrame({"a": [3.6, 4.9]}, index=[0, 1]), + 4, + pd.DataFrame({"a": [False, True]}, index=[0, 1]) + ), + # Test with integer column labels + ( + pd.DataFrame({1: [14.0, 26.0]}, index=[0, 1]), + 15, + pd.DataFrame({1: [False, True]}, index=[0, 1]) + ), + # Test with a False case (a < b) + ( + pd.DataFrame({"a": [6.0]}, index=["row1"]), + 7, + pd.DataFrame({"a": [False]}, index=["row1"]) + ), + # Another False case with an integer column label + ( + pd.DataFrame({2: [7]}, index=["row1"]), + 7, + 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() diff --git a/tests/pandas_wrapper/pandas_le_scalar_float_test.py b/tests/pandas_wrapper/pandas_le_scalar_float_test.py new file mode 100644 index 0000000..36770c7 --- /dev/null +++ b/tests/pandas_wrapper/pandas_le_scalar_float_test.py @@ -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_scalar_float import PandasLeScalarFloat + +class TestPandasLeScalarFloat(unittest.TestCase): + def setUp(self): + """Set up test data.""" + self.node = PandasLeScalarFloat() + self.test_cases = [ + # Test where all values are True + ( + pd.DataFrame({"a": [1.5, 2.5]}, index=["row1", "row2"]), + 3.1, + pd.DataFrame({"a": [True, True]}, index=["row1", "row2"]) + ), + # Test with integer (still True) + ( + pd.DataFrame({"a": [3, 4]}, index=[0, 1]), + 5.1, + pd.DataFrame({"a": [True, True]}, index=[0, 1]) + ), + # Test with integer column labels (True) + ( + pd.DataFrame({1: [10.0, 25.1]}, index=[0, 1]), + 25.1, + pd.DataFrame({1: [True, True]}, index=[0, 1]) + ), + # Test with a False case (a > b) + ( + pd.DataFrame({"a": [7.0]}, index=["row1"]), + 6.5, + pd.DataFrame({"a": [False]}, index=["row1"]) + ), + # Another False case with an integer column label + ( + pd.DataFrame({2: [9.5]}, index=["row1"]), + 8.1, + 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() diff --git a/tests/pandas_wrapper/pandas_le_scalar_int_test.py b/tests/pandas_wrapper/pandas_le_scalar_int_test.py new file mode 100644 index 0000000..948a469 --- /dev/null +++ b/tests/pandas_wrapper/pandas_le_scalar_int_test.py @@ -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_scalar_int import PandasLeScalarInt + +class TestPandasLeScalarInt(unittest.TestCase): + def setUp(self): + """Set up test data.""" + self.node = PandasLeScalarInt() + self.test_cases = [ + # Test where all values are True + ( + pd.DataFrame({"a": [1.5, 2.5]}, index=["row1", "row2"]), + 3, + pd.DataFrame({"a": [True, True]}, index=["row1", "row2"]) + ), + # Test with integer (still True) + ( + pd.DataFrame({"a": [3, 4]}, index=[0, 1]), + 5, + pd.DataFrame({"a": [True, True]}, index=[0, 1]) + ), + # Test with integer column labels (True) + ( + pd.DataFrame({1: [10.0, 25]}, index=[0, 1]), + 25, + pd.DataFrame({1: [True, True]}, index=[0, 1]) + ), + # Test with a False case (a > b) + ( + pd.DataFrame({"a": [7.0]}, index=["row1"]), + 6, + pd.DataFrame({"a": [False]}, index=["row1"]) + ), + # Another False case with an integer column label + ( + pd.DataFrame({2: [9.5]}, index=["row1"]), + 8, + 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() diff --git a/tests/pandas_wrapper/pandas_lt_scalar_float_test.py b/tests/pandas_wrapper/pandas_lt_scalar_float_test.py new file mode 100644 index 0000000..a112afb --- /dev/null +++ b/tests/pandas_wrapper/pandas_lt_scalar_float_test.py @@ -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_scalar_float import PandasLtScalarFloat + +class TestPandasLeScalarFloat(unittest.TestCase): + def setUp(self): + """Set up test data.""" + self.node = PandasLtScalarFloat() + self.test_cases = [ + # Test where all values are True + ( + pd.DataFrame({"a": [1.5, 2.5]}, index=["row1", "row2"]), + 3.1, + pd.DataFrame({"a": [True, True]}, index=["row1", "row2"]) + ), + # Test with integer (still True) + ( + pd.DataFrame({"a": [3, 4]}, index=[0, 1]), + 5.1, + pd.DataFrame({"a": [True, True]}, index=[0, 1]) + ), + # Test with integer column labels + ( + pd.DataFrame({1: [10.0, 25.1]}, index=[0, 1]), + 25.1, + pd.DataFrame({1: [True, False]}, index=[0, 1]) + ), + # Test with a False case (a > b) + ( + pd.DataFrame({"a": [7.0]}, index=["row1"]), + 6.5, + pd.DataFrame({"a": [False]}, index=["row1"]) + ), + # Another False case with an integer column label + ( + pd.DataFrame({2: [9.5]}, index=["row1"]), + 8.1, + 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() diff --git a/tests/pandas_wrapper/pandas_lt_scalar_int_test.py b/tests/pandas_wrapper/pandas_lt_scalar_int_test.py new file mode 100644 index 0000000..9b8d17e --- /dev/null +++ b/tests/pandas_wrapper/pandas_lt_scalar_int_test.py @@ -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_scalar_int import PandasLtScalarInt + +class TestPandasLtScalarInt(unittest.TestCase): + def setUp(self): + """Set up test data.""" + self.node = PandasLtScalarInt() + self.test_cases = [ + # Test where all values are True + ( + pd.DataFrame({"a": [1.5, 2.5]}, index=["row1", "row2"]), + 3, + pd.DataFrame({"a": [True, True]}, index=["row1", "row2"]) + ), + # Test with integer (still True) + ( + pd.DataFrame({"a": [3, 4]}, index=[0, 1]), + 5, + pd.DataFrame({"a": [True, True]}, index=[0, 1]) + ), + # Test with integer column labels (True) + ( + pd.DataFrame({1: [10.0, 25]}, index=[0, 1]), + 25, + pd.DataFrame({1: [True, False]}, index=[0, 1]) + ), + # Test with a False case (a > b) + ( + pd.DataFrame({"a": [7.0]}, index=["row1"]), + 6, + pd.DataFrame({"a": [False]}, index=["row1"]) + ), + # Another False case with an integer column label + ( + pd.DataFrame({2: [9.5]}, index=["row1"]), + 8, + 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() diff --git a/tests/pandas_wrapper/pandas_ne_scalar_float_test.py b/tests/pandas_wrapper/pandas_ne_scalar_float_test.py new file mode 100644 index 0000000..a72f99c --- /dev/null +++ b/tests/pandas_wrapper/pandas_ne_scalar_float_test.py @@ -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_scalar_float import PandasNeScalarFloat + +class TestPandasNeScalarFloat(unittest.TestCase): + def setUp(self): + """Set up test data.""" + self.node = PandasNeScalarFloat() + self.test_cases = [ + # Test where all values are True + ( + pd.DataFrame({"a": [2.5, 3.5]}, index=["row1", "row2"]), + 2.1, + pd.DataFrame({"a": [True, True]}, index=["row1", "row2"]) + ), + # Test with mixed result + ( + pd.DataFrame({"a": [3.6, 4.9]}, index=[0, 1]), + 4.9, + pd.DataFrame({"a": [True, False]}, index=[0, 1]) + ), + # Test with integer column labels + ( + pd.DataFrame({1: [14.0, 26.0]}, index=[0, 1]), + 14.0, + pd.DataFrame({1: [False, True]}, index=[0, 1]) + ), + # Test with a False case + ( + pd.DataFrame({"a": [6.0]}, index=["row1"]), + 6.0, + pd.DataFrame({"a": [False]}, index=["row1"]) + ), + # Another False case with an integer column label + ( + pd.DataFrame({2: [7.5]}, index=["row1"]), + 7.5, + pd.DataFrame({2: [False]}, index=["row1"]) + ), + ] + + def test_ne_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() diff --git a/tests/pandas_wrapper/pandas_ne_scalar_int_test.py b/tests/pandas_wrapper/pandas_ne_scalar_int_test.py new file mode 100644 index 0000000..b7e5012 --- /dev/null +++ b/tests/pandas_wrapper/pandas_ne_scalar_int_test.py @@ -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_scalar_int import PandasNeScalarInt + +class TestPandasNeScalarFloat(unittest.TestCase): + def setUp(self): + """Set up test data.""" + self.node = PandasNeScalarInt() + self.test_cases = [ + # Test where all values are True + ( + pd.DataFrame({"a": [2.5, 3.5]}, index=["row1", "row2"]), + 2, + pd.DataFrame({"a": [True, True]}, index=["row1", "row2"]) + ), + # Test with mixed result + ( + pd.DataFrame({"a": [3.6, 4]}, index=[0, 1]), + 4, + pd.DataFrame({"a": [True, False]}, index=[0, 1]) + ), + # Test with integer column labels + ( + pd.DataFrame({1: [14, 26.0]}, index=[0, 1]), + 14, + pd.DataFrame({1: [False, True]}, index=[0, 1]) + ), + # Test with a False case + ( + pd.DataFrame({"a": [6]}, index=["row1"]), + 6, + pd.DataFrame({"a": [False]}, index=["row1"]) + ), + # Another False case with an integer column label + ( + pd.DataFrame({2: [8]}, index=["row1"]), + 8, + pd.DataFrame({2: [False]}, index=["row1"]) + ), + ] + + def test_ne_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() diff --git a/tests/pandas_wrapper/pandas_select_column_as_series_test.py b/tests/pandas_wrapper/pandas_select_column_as_series_test.py new file mode 100644 index 0000000..d4cda21 --- /dev/null +++ b/tests/pandas_wrapper/pandas_select_column_as_series_test.py @@ -0,0 +1,52 @@ +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_select_column_as_series import PandasSelectColumnAsSeries + +class TestPandasSelectColumnAsSeries(unittest.TestCase): + def setUp(self): + """Set up test data.""" + self.node = PandasSelectColumnAsSeries() + self.test_cases = [ + # Test with a simple DataFrame + ( + pd.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]}), + "a", + pd.Series([1, 2, 3], name="a") + ), + # Test with a DataFrame with different data types + ( + pd.DataFrame({"x": ["foo", "bar"], "y": [10.5, 20.5]}), + "y", + pd.Series([10.5, 20.5], name="y") + ), + # Test with integer column labels + ( + pd.DataFrame({1: [100, 200], 2: [300, 400]}), + 1, + pd.Series([100, 200], name=1) + ), + # Test with single-row DataFrame + ( + pd.DataFrame({"col": [42]}), + "col", + pd.Series([42], name="col") + ), + ] + + def test_select_column_as_series(self): + """Test selecting a column as a pandas Series.""" + for df, column_name, expected in self.test_cases: + with self.subTest(df=df, column_name=column_name): + retval = self.node.f(df, column_name) + self.assertIsInstance(retval, tuple, "Return value should be a tuple.") + self.assertEqual(len(retval), 1, "Return tuple should have a single Series.") + pd.testing.assert_series_equal(retval[0], expected) + +if __name__ == "__main__": + unittest.main() \ No newline at end of file