diff --git a/__init__.py b/__init__.py index 8f3ce5c..7c0423a 100644 --- a/__init__.py +++ b/__init__.py @@ -17,6 +17,7 @@ from .modules.pandas_wrapper.pandas_div_series import PandasDivSeries from .modules.pandas_wrapper.pandas_dropna import PandasDropNA 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_iloc_row_series import PandasIlocRowSeries from .modules.pandas_wrapper.pandas_iloc_rows_dataframe import PandasIlocRowsDataFrame from .modules.pandas_wrapper.pandas_index import PandasIndex @@ -55,6 +56,7 @@ from .modules.pandas_wrapper.pandas_sum import PandasSum 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 T = TypeVar("T") @@ -78,6 +80,7 @@ NODE_CLASS_MAPPINGS: Dict[str, Type[T]] = { "PandasDropNA": PandasDropNA, "PandasGroupBy": PandasGroupBy, "PandasHead": PandasHead, + "PandasHorizontalConcat": PandasHorizontalConcat, "PandasIlocRowSeries": PandasIlocRowSeries, "PandasIlocRowsDataFrame": PandasIlocRowsDataFrame, "PandasIndex": PandasIndex, @@ -115,7 +118,8 @@ NODE_CLASS_MAPPINGS: Dict[str, Type[T]] = { "PandasSum": PandasSum, "PandasSummary": PandasSummary, "PandasToString": PandasToString, - "PandasVar": PandasVar + "PandasVar": PandasVar, + "PandasVerticalConcat": PandasVerticalConcat } """ NODE_CLASS_MAPPINGS (Dict[str, Type[T]]): @@ -141,6 +145,7 @@ NODE_DISPLAY_NAME_MAPPINGS: Dict[str, str] = { "PandasDropNA": "Pandas Drop NA", "PandasGroupBy": "Pandas Group By", "PandasHead": "Pandas Head", + "PandasHorizontalConcat": "Pandas Horizontal Concat", "PandasIlocRowSeries": "Pandas Iloc Row Series", "PandasIlocRowsDataFrame": "Pandas Iloc Rows DataFrame", "PandasIndex": "Pandas Index", @@ -179,6 +184,7 @@ NODE_DISPLAY_NAME_MAPPINGS: Dict[str, str] = { "PandasSummary": "Pandas Summary", "PandasToString": "Pandas To String", "PandasVar": "Pandas Var", + "PandasVerticalConcat": "Pandas Vertical Concat" } """ NODE_DISPLAY_NAME_MAPPINGS (Dict[str, str]): diff --git a/docs/images/concat.png b/docs/images/concat.png new file mode 100644 index 0000000..703989f Binary files /dev/null and b/docs/images/concat.png differ diff --git a/docs/ug.md b/docs/ug.md index 3d04f17..532f942 100644 --- a/docs/ug.md +++ b/docs/ug.md @@ -79,6 +79,8 @@ This page was initially created using an older version of ComfyUI Data Analysis, | **Pandas Mul** | Multiply two DataFrames | | **Pandas Pow** | Raise a DataFrame to the power of another DataFrame | | **Pandas Sub** | Subtract a DataFrame from another DataFrame | +| **Pandas Horizontal Concat** | Concatenate two DataFrames horizontally (axis=1) | +| **Pandas Vertical Concat** | Concatenate two DataFrames vertically (axis=0) | **Binary operators for a DataFrame and a Series** | Node Name | Functionality | @@ -272,6 +274,10 @@ For binary operation for two DataFrames, you can use below operators: | **Pandas Mul** | Multiply two DataFrames | | **Pandas Pow** | Raise a DataFrame to the power of another DataFrame | | **Pandas Sub** | Subtract a DataFrame from another DataFrame | +| **Pandas Horizontal Concat** | Concatenate two DataFrames horizontally (axis=1) | +| **Pandas Vertical Concat** | Concatenate two DataFrames vertically (axis=0) | + +![Pandas Vertical Concat & Horizontal Concat](images/concat.png) For binary operation for a DataFrame and a Series, you can use below operators: | Node Name | Functionality | diff --git a/examples/workflows/concat.json b/examples/workflows/concat.json new file mode 100644 index 0000000..435c842 --- /dev/null +++ b/examples/workflows/concat.json @@ -0,0 +1 @@ +{"last_node_id":16,"last_link_id":14,"nodes":[{"id":5,"type":"PandasCreate","pos":[340.3745422363281,2836.533935546875],"size":[210,94.9962158203125],"flags":{},"order":0,"mode":0,"inputs":[],"outputs":[{"name":"DATAFRAME","type":"DATAFRAME","links":[11],"slot_index":0,"localized_name":"DATAFRAME"}],"properties":{"Node name for S&R":"PandasCreate"},"widgets_values":["A,B\n500,5000\n600,6000"]},{"id":15,"type":"PandasCreate","pos":[340.7720031738281,2668.344970703125],"size":[210,106.02879333496094],"flags":{},"order":1,"mode":0,"inputs":[],"outputs":[{"name":"DATAFRAME","type":"DATAFRAME","links":[13],"slot_index":0,"localized_name":"DATAFRAME"}],"properties":{"Node name for S&R":"PandasCreate"},"widgets_values":["A,B\n1,10\n2,20"]},{"id":14,"type":"PandasCreate","pos":[340.77191162109375,2421.255126953125],"size":[210,94.9962158203125],"flags":{},"order":2,"mode":0,"inputs":[],"outputs":[{"name":"DATAFRAME","type":"DATAFRAME","links":[14],"slot_index":0,"localized_name":"DATAFRAME"}],"properties":{"Node name for S&R":"PandasCreate"},"widgets_values":["C,D\n500,5000\n600,6000"]},{"id":4,"type":"PandasCreate","pos":[342.41656494140625,2254.481201171875],"size":[210,106.02879333496094],"flags":{},"order":3,"mode":0,"inputs":[],"outputs":[{"name":"DATAFRAME","type":"DATAFRAME","links":[4],"slot_index":0,"localized_name":"DATAFRAME"}],"properties":{"Node name for S&R":"PandasCreate"},"widgets_values":["A,B\n1,10\n2,20"]},{"id":6,"type":"PandasHorizontalConcat","pos":[682.4112548828125,2363.37939453125],"size":[302.4000244140625,46],"flags":{},"order":5,"mode":0,"inputs":[{"name":"a_dataframe","type":"DATAFRAME","link":4,"localized_name":"a_dataframe"},{"name":"b_dataframe","type":"DATAFRAME","link":14,"localized_name":"b_dataframe"}],"outputs":[{"name":"DATAFRAME","type":"DATAFRAME","links":[6],"slot_index":0,"localized_name":"DATAFRAME"}],"properties":{"Node name for S&R":"PandasHorizontalConcat"},"widgets_values":[]},{"id":2,"type":"PandasShowDataFrame","pos":[1043.4501953125,2363.7451171875],"size":[210,104.60636138916016],"flags":{},"order":7,"mode":0,"inputs":[{"name":"dataframe","type":"DATAFRAME","link":6,"localized_name":"dataframe"}],"outputs":[{"name":"STRING","type":"STRING","links":[],"slot_index":0,"shape":6,"localized_name":"STRING"}],"properties":{"Node name for S&R":"PandasShowDataFrame"},"widgets_values":[" A B C D\n0 1 10 500 5000\n1 2 20 600 6000"]},{"id":13,"type":"PandasVerticalConcat","pos":[684.0742797851562,2751.436767578125],"size":[267,46],"flags":{},"order":4,"mode":0,"inputs":[{"name":"a_dataframe","type":"DATAFRAME","link":13,"localized_name":"a_dataframe"},{"name":"b_dataframe","type":"DATAFRAME","link":11,"localized_name":"b_dataframe"}],"outputs":[{"name":"DATAFRAME","type":"DATAFRAME","links":[12],"slot_index":0,"localized_name":"DATAFRAME"}],"properties":{"Node name for S&R":"PandasVerticalConcat"},"widgets_values":[]},{"id":12,"type":"PandasShowDataFrame","pos":[1046.1783447265625,2746.99560546875],"size":[210,178.95204162597656],"flags":{},"order":6,"mode":0,"inputs":[{"name":"dataframe","type":"DATAFRAME","link":12,"localized_name":"dataframe"}],"outputs":[{"name":"STRING","type":"STRING","links":[],"slot_index":0,"shape":6,"localized_name":"STRING"}],"properties":{"Node name for S&R":"PandasShowDataFrame"},"widgets_values":[" A B\n0 1 10\n1 2 20\n2 500 5000\n3 600 6000"]}],"links":[[4,4,0,6,0,"DATAFRAME"],[6,6,0,2,0,"DATAFRAME"],[11,5,0,13,1,"DATAFRAME"],[12,13,0,12,0,"DATAFRAME"],[13,15,0,13,0,"DATAFRAME"],[14,14,0,6,1,"DATAFRAME"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.7622054019658013,"offset":[41.88950958615887,-1970.1509315749547]},"node_versions":{"data-analysis":"63c4dadeb8ece016f51f3beca9266a33a508d313"},"ue_links":[]},"version":0.4} \ No newline at end of file diff --git a/modules/pandas_wrapper/pandas_horizontal_concat.py b/modules/pandas_wrapper/pandas_horizontal_concat.py new file mode 100644 index 0000000..098e813 --- /dev/null +++ b/modules/pandas_wrapper/pandas_horizontal_concat.py @@ -0,0 +1,42 @@ +from typing import Any, Dict +import pandas as pd + + +class PandasHorizontalConcat: + """ + PandasHorizontalConcat: + A class for horizontally concatenating two pandas DataFrames. + """ + + @classmethod + def INPUT_TYPES(cls) -> Dict[str, Any]: + """ + Defines the input types for the function. + + Returns: + Dict[str, Any]: A dictionary specifying required input types. + """ + return { + "required": { + "a_dataframe": ("DATAFRAME", {}), + "b_dataframe": ("DATAFRAME", {}) + } + } + + RETURN_TYPES: tuple = ("DATAFRAME",) + FUNCTION: str = "f" + CATEGORY: str = "Data Analysis" + + def f(self, a_dataframe: pd.DataFrame, b_dataframe: pd.DataFrame) -> tuple: + """ + Horizontally concatenate two pandas DataFrames. + + Args: + a_dataframe (DataFrame): The first DataFrame. + b_dataframe (DataFrame): The second DataFrame. + + Returns: + tuple: A tuple containing the concatenated DataFrame. + """ + df_out = pd.concat([a_dataframe, b_dataframe], axis=1) + return (df_out,) diff --git a/modules/pandas_wrapper/pandas_vertical_concat.py b/modules/pandas_wrapper/pandas_vertical_concat.py new file mode 100644 index 0000000..a2d8681 --- /dev/null +++ b/modules/pandas_wrapper/pandas_vertical_concat.py @@ -0,0 +1,42 @@ +from typing import Any, Dict +import pandas as pd + + +class PandasVerticalConcat: + """ + PandasVerticalConcat: + A class for vertically concatenating two pandas DataFrames. + """ + + @classmethod + def INPUT_TYPES(cls) -> Dict[str, Any]: + """ + Defines the input types for the function. + + Returns: + Dict[str, Any]: A dictionary specifying required input types. + """ + return { + "required": { + "a_dataframe": ("DATAFRAME", {}), + "b_dataframe": ("DATAFRAME", {}) + } + } + + RETURN_TYPES: tuple = ("DATAFRAME",) + FUNCTION: str = "f" + CATEGORY: str = "Data Analysis" + + def f(self, a_dataframe: pd.DataFrame, b_dataframe: pd.DataFrame) -> tuple: + """ + Vertically concatenate two pandas DataFrames. + + Args: + a_dataframe (DataFrame): The first DataFrame. + b_dataframe (DataFrame): The second DataFrame. + + Returns: + tuple: A tuple containing the concatenated DataFrame. + """ + df_out = pd.concat([a_dataframe, b_dataframe], axis=0, ignore_index=True) + return (df_out,) diff --git a/pyproject.toml b/pyproject.toml index 99bbc24..969f5c1 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.1" +version = "1.1.2" license = {file = "LICENSE"} [project.urls]