From 345d9642da7f45ec05a922a653f0a2dd88b20b7f Mon Sep 17 00:00:00 2001 From: HowToSD Date: Tue, 18 Feb 2025 21:16:52 -0800 Subject: [PATCH] Added Pandas Horizontal Split and Vertical Split nodes. --- __init__.py | 11 +++-- docs/reference/node_reference.md | 2 + docs/reference/pandas_horizontal_split.md | 19 +++++++ docs/reference/pandas_vertical_split.md | 19 +++++++ examples/workflows/split.json | 1 + .../pandas_wrapper/pandas_horizontal_split.py | 49 +++++++++++++++++++ .../pandas_wrapper/pandas_vertical_split.py | 49 +++++++++++++++++++ pyproject.toml | 2 +- 8 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 docs/reference/pandas_horizontal_split.md create mode 100644 docs/reference/pandas_vertical_split.md create mode 100644 examples/workflows/split.json create mode 100644 modules/pandas_wrapper/pandas_horizontal_split.py create mode 100644 modules/pandas_wrapper/pandas_vertical_split.py diff --git a/__init__.py b/__init__.py index 5969db3..cbd36d8 100644 --- a/__init__.py +++ b/__init__.py @@ -23,6 +23,7 @@ from .modules.pandas_wrapper.pandas_tan import PandasTan from .modules.pandas_wrapper.pandas_group_by import PandasGroupBy 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 from .modules.pandas_wrapper.pandas_iloc_row_series import PandasIlocRowSeries from .modules.pandas_wrapper.pandas_iloc_rows_dataframe import PandasIlocRowsDataFrame from .modules.pandas_wrapper.pandas_index import PandasIndex @@ -62,7 +63,7 @@ from .modules.pandas_wrapper.pandas_summary import PandasSummary from .modules.pandas_wrapper.pandas_to_string import PandasToString from .modules.pandas_wrapper.pandas_var import PandasVar from .modules.pandas_wrapper.pandas_vertical_concat import PandasVerticalConcat - +from .modules.pandas_wrapper.pandas_vertical_split import PandasVerticalSplit T = TypeVar("T") @@ -91,6 +92,7 @@ NODE_CLASS_MAPPINGS: Dict[str, Type[T]] = { "PandasGroupBy": PandasGroupBy, "PandasHead": PandasHead, "PandasHorizontalConcat": PandasHorizontalConcat, + "PandasHorizontalSplit": PandasHorizontalSplit, "PandasIlocRowSeries": PandasIlocRowSeries, "PandasIlocRowsDataFrame": PandasIlocRowsDataFrame, "PandasIndex": PandasIndex, @@ -129,7 +131,8 @@ NODE_CLASS_MAPPINGS: Dict[str, Type[T]] = { "PandasSummary": PandasSummary, "PandasToString": PandasToString, "PandasVar": PandasVar, - "PandasVerticalConcat": PandasVerticalConcat + "PandasVerticalConcat": PandasVerticalConcat, + "PandasVerticalSplit": PandasVerticalSplit } """ NODE_CLASS_MAPPINGS (Dict[str, Type[T]]): @@ -161,6 +164,7 @@ NODE_DISPLAY_NAME_MAPPINGS: Dict[str, str] = { "PandasGroupBy": "Pandas Group By", "PandasHead": "Pandas Head", "PandasHorizontalConcat": "Pandas Horizontal Concat", + "PandasHorizontalSplit": "Pandas Horizontal Split", "PandasIlocRowSeries": "Pandas Iloc Row Series", "PandasIlocRowsDataFrame": "Pandas Iloc Rows DataFrame", "PandasIndex": "Pandas Index", @@ -199,7 +203,8 @@ NODE_DISPLAY_NAME_MAPPINGS: Dict[str, str] = { "PandasSummary": "Pandas Summary", "PandasToString": "Pandas To String", "PandasVar": "Pandas Var", - "PandasVerticalConcat": "Pandas Vertical Concat" + "PandasVerticalConcat": "Pandas Vertical Concat", + "PandasVerticalSplit": "Pandas Vertical Split" } """ NODE_DISPLAY_NAME_MAPPINGS (Dict[str, str]): diff --git a/docs/reference/node_reference.md b/docs/reference/node_reference.md index 9956cc6..2035082 100644 --- a/docs/reference/node_reference.md +++ b/docs/reference/node_reference.md @@ -95,6 +95,8 @@ | Node | Description | | --- | --- | | [Pandas Horizontal Concat](pandas_horizontal_concat.md) | Horizontally concatenates two pandas DataFrames. | +| [Pandas Horizontal Split](pandas_horizontal_split.md) | Horizontally splits a Pandas DataFrame into two pandas DataFrames. | | [Pandas Join](pandas_join.md) | Merges two pandas DataFrames based on a common column. | | [Pandas Sort](pandas_sort.md) | Sorts a pandas DataFrame by a specified column. | | [Pandas Vertical Concat](pandas_vertical_concat.md) | Vertically concatenates two pandas DataFrames. | +| [Pandas Vertical Split](pandas_vertical_split.md) | Vertically splits a Pandas DataFrame into two pandas DataFrames. | diff --git a/docs/reference/pandas_horizontal_split.md b/docs/reference/pandas_horizontal_split.md new file mode 100644 index 0000000..3e990bc --- /dev/null +++ b/docs/reference/pandas_horizontal_split.md @@ -0,0 +1,19 @@ +# Pandas Horizontal Split +Horizontally splits a Pandas DataFrame into two pandas DataFrames. + +## Input +| Name | Data type | +|---|---| +| dataframe | DataFrame | +| column_integer_position | Int | + +## Output +| Data type | +|---| +| DataFrame | +| DataFrame | + +
+Category: Transformation + +ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/docs/reference/pandas_vertical_split.md b/docs/reference/pandas_vertical_split.md new file mode 100644 index 0000000..3a3bdf4 --- /dev/null +++ b/docs/reference/pandas_vertical_split.md @@ -0,0 +1,19 @@ +# Pandas Vertical Split +Vertically splits a Pandas DataFrame into two pandas DataFrames. + +## Input +| Name | Data type | +|---|---| +| dataframe | DataFrame | +| row_integer_position | Int | + +## Output +| Data type | +|---| +| DataFrame | +| DataFrame | + +
+Category: Transformation + +ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/examples/workflows/split.json b/examples/workflows/split.json new file mode 100644 index 0000000..4587ec1 --- /dev/null +++ b/examples/workflows/split.json @@ -0,0 +1 @@ +{"last_node_id":70,"last_link_id":74,"nodes":[{"id":68,"type":"PandasHorizontalSplit","pos":[-126.66181182861328,2918.54736328125],"size":[317.4000244140625,78],"flags":{},"order":3,"mode":0,"inputs":[{"name":"dataframe","type":"DATAFRAME","link":74}],"outputs":[{"name":"Left DataFrame","type":"DATAFRAME","links":[72],"slot_index":0},{"name":"Right DataFrame","type":"DATAFRAME","links":[73],"slot_index":1}],"properties":{"Node name for S&R":"PandasHorizontalSplit"},"widgets_values":[1]},{"id":69,"type":"PandasShowDataFrame","pos":[485.1441345214844,3092.146484375],"size":[210,121.16669464111328],"flags":{},"order":7,"mode":0,"inputs":[{"name":"dataframe","type":"DATAFRAME","link":73}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6}],"properties":{"Node name for S&R":"PandasShowDataFrame"},"widgets_values":[" B C\n0 12.3 Dog\n1 23.4 Cat\n2 34.5 Rabbit"]},{"id":64,"type":"PandasCreate","pos":[-300.70599365234375,2670.06005859375],"size":[210,123.86104583740234],"flags":{},"order":0,"mode":0,"inputs":[],"outputs":[{"name":"DATAFRAME","type":"DATAFRAME","links":[68,71,74],"slot_index":0}],"properties":{"Node name for S&R":"PandasCreate"},"widgets_values":["A,B,C\n10,12.3,Dog\n20,23.4,Cat\n30,34.5,Rabbit"]},{"id":70,"type":"PandasShowDataFrame","pos":[218.49526977539062,3108.108642578125],"size":[210,103.45830535888672],"flags":{},"order":6,"mode":0,"inputs":[{"name":"dataframe","type":"DATAFRAME","link":72}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6}],"properties":{"Node name for S&R":"PandasShowDataFrame"},"widgets_values":[" A\n0 10\n1 20\n2 30"]},{"id":32,"type":"PandasShowDataFrame","pos":[-20.655092239379883,2675.75244140625],"size":[210,104.88404083251953],"flags":{},"order":2,"mode":0,"inputs":[{"name":"dataframe","type":"DATAFRAME","link":71}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6}],"properties":{"Node name for S&R":"PandasShowDataFrame"},"widgets_values":[" A B C\n0 10 12.3 Dog\n1 20 23.4 Cat\n2 30 34.5 Rabbit"]},{"id":65,"type":"PandasVerticalSplit","pos":[-134.28067016601562,2448.783203125],"size":[330,78],"flags":{},"order":1,"mode":0,"inputs":[{"name":"dataframe","type":"DATAFRAME","link":68}],"outputs":[{"name":"Top DataFrame","type":"DATAFRAME","links":[69],"slot_index":0},{"name":"Bottom DataFrame","type":"DATAFRAME","links":[70],"slot_index":1}],"properties":{"Node name for S&R":"PandasVerticalSplit"},"widgets_values":[2]},{"id":67,"type":"PandasShowDataFrame","pos":[229.82748413085938,2517.0009765625],"size":[272.933349609375,101],"flags":{},"order":5,"mode":0,"inputs":[{"name":"dataframe","type":"DATAFRAME","link":70}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6}],"properties":{"Node name for S&R":"PandasShowDataFrame"},"widgets_values":[" A B C\n2 30 34.5 Rabbit"]},{"id":66,"type":"PandasShowDataFrame","pos":[230.1259307861328,2341.906982421875],"size":[260.433349609375,108.5],"flags":{},"order":4,"mode":0,"inputs":[{"name":"dataframe","type":"DATAFRAME","link":69}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6}],"properties":{"Node name for S&R":"PandasShowDataFrame"},"widgets_values":[" A B C\n0 10 12.3 Dog\n1 20 23.4 Cat"]}],"links":[[68,64,0,65,0,"DATAFRAME"],[69,65,0,66,0,"DATAFRAME"],[70,65,1,67,0,"DATAFRAME"],[71,64,0,32,0,"DATAFRAME"],[72,68,0,70,0,"DATAFRAME"],[73,68,1,69,0,"DATAFRAME"],[74,64,0,68,0,"DATAFRAME"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.8264462809917354,"offset":[380.23215878327846,-2286.7820859816943]},"node_versions":{"data-analysis":"a5de56622e0e408bdf3d7488fca526526a2d3ec2"},"ue_links":[]},"version":0.4} \ No newline at end of file diff --git a/modules/pandas_wrapper/pandas_horizontal_split.py b/modules/pandas_wrapper/pandas_horizontal_split.py new file mode 100644 index 0000000..fa886da --- /dev/null +++ b/modules/pandas_wrapper/pandas_horizontal_split.py @@ -0,0 +1,49 @@ +from typing import Any, Dict +import pandas as pd + + +class PandasHorizontalSplit: + """ + Horizontally splits a Pandas DataFrame into two pandas DataFrames. + + category: Transformation + """ + + @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_integer_position": ("INT", {"default": 0, "min": -1, "max": 2**31}) + } + } + + RETURN_TYPES: tuple = ("DATAFRAME", "DATAFRAME") + RETURN_NAMES: tuple = ("Left DataFrame", "Right DataFrame") + + FUNCTION: str = "f" + CATEGORY: str = "Data Analysis" + + def f(self, dataframe: pd.DataFrame, column_integer_position: int) -> tuple: + """ + Horizontally splits a Pandas DataFrame into two pandas DataFrames. + + Args: + dataframe (pd.DataFrame): The DataFrame to split. + column_integer_position (int): The column integer position where the split occurs. + The left DataFrame contains columns [0, column_integer_position-1], + and the right DataFrame contains columns [column_integer_position, end]. + + Returns: + tuple: A tuple containing the left and right DataFrames. + """ + df_left = dataframe.iloc[:,:column_integer_position] + df_right = dataframe.iloc[:,column_integer_position:] + + return (df_left, df_right) diff --git a/modules/pandas_wrapper/pandas_vertical_split.py b/modules/pandas_wrapper/pandas_vertical_split.py new file mode 100644 index 0000000..47588c9 --- /dev/null +++ b/modules/pandas_wrapper/pandas_vertical_split.py @@ -0,0 +1,49 @@ +from typing import Any, Dict +import pandas as pd + + +class PandasVerticalSplit: + """ + Vertically splits a Pandas DataFrame into two pandas DataFrames. + + category: Transformation + """ + + @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", {}), + "row_integer_position": ("INT", {"default": 0, "min": -1, "max": 2**31}) + } + } + + RETURN_TYPES: tuple = ("DATAFRAME", "DATAFRAME") + RETURN_NAMES: tuple = ("Top DataFrame", "Bottom DataFrame") + + FUNCTION: str = "f" + CATEGORY: str = "Data Analysis" + + def f(self, dataframe: pd.DataFrame, row_integer_position: int) -> tuple: + """ + Vertically splits a Pandas DataFrame into two pandas DataFrames. + + Args: + dataframe (pd.DataFrame): The DataFrame to split. + row_integer_position (int): The row integer position where the split occurs. + The top DataFrame contains rows [0, row_integer_position-1], + and the bottom DataFrame contains rows [row_integer_position, end]. + + Returns: + tuple: A tuple containing the top and bottom DataFrames. + """ + df_top = dataframe.iloc[:row_integer_position] + df_bottom = dataframe.iloc[row_integer_position:] + + return (df_top, df_bottom) diff --git a/pyproject.toml b/pyproject.toml index 014035f..2f3dd8f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "data-analysis" description = "Data analysis custom modules for ComfyUI - Use Pandas & Matplotlib within ComfyUI" -version = "1.1.5" +version = "1.1.6" license = {file = "LICENSE"} [project.urls]