diff --git a/__init__.py b/__init__.py index fd4722e..66c65de 100644 --- a/__init__.py +++ b/__init__.py @@ -74,6 +74,7 @@ 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 from .modules.pandas_wrapper.pandas_series_to_string import PandasSeriesToString +from .modules.pandas_wrapper.pandas_set_index import PandasSetIndex from .modules.pandas_wrapper.pandas_show_dataframe import PandasShowDataFrame from .modules.pandas_wrapper.pandas_show_index import PandasShowIndex from .modules.pandas_wrapper.pandas_show_series import PandasShowSeries @@ -176,6 +177,7 @@ NODE_CLASS_MAPPINGS: Dict[str, Type[T]] = { "PandasSelectRows": PandasSelectRows, "PandasSeriesToDataFrame": PandasSeriesToDataFrame, "PandasSeriesToString": PandasSeriesToString, + "PandasSetIndex": PandasSetIndex, "PandasShowDataFrame": PandasShowDataFrame, "PandasShowIndex": PandasShowIndex, "PandasShowSeries": PandasShowSeries, @@ -278,6 +280,7 @@ NODE_DISPLAY_NAME_MAPPINGS: Dict[str, str] = { "PandasSelectRows": "Pandas Select Rows", "PandasSeriesToDataFrame": "Pandas Series To DataFrame", "PandasSeriesToString": "Pandas Series To String", + "PandasSetIndex": "Pandas Set Index", "PandasShowDataFrame": "Pandas Show DataFrame", "PandasShowIndex": "Pandas Show Index", "PandasShowSeries": "Pandas Show Series", diff --git a/docs/images/set_index1.png b/docs/images/set_index1.png new file mode 100644 index 0000000..652aa8b Binary files /dev/null and b/docs/images/set_index1.png differ diff --git a/docs/images/set_index2.png b/docs/images/set_index2.png new file mode 100644 index 0000000..04a75e1 Binary files /dev/null and b/docs/images/set_index2.png differ diff --git a/docs/reference/node_reference.md b/docs/reference/node_reference.md index 4206e2b..091a7a7 100644 --- a/docs/reference/node_reference.md +++ b/docs/reference/node_reference.md @@ -52,6 +52,10 @@ | [Pandas Loc Row Series](pandas_loc_row_series.md) | Selects a row from a pandas DataFrame and output as a Series. | | [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. | +## Data transformation +| Node | Description | +| --- | --- | +| [Pandas Set Index](pandas_set_index.md) | Create index (row label) from existing column or columns. | ## Data type conversion | Node | Description | | --- | --- | diff --git a/docs/reference/pandas_set_index.md b/docs/reference/pandas_set_index.md new file mode 100644 index 0000000..14b8f65 --- /dev/null +++ b/docs/reference/pandas_set_index.md @@ -0,0 +1,33 @@ +# Pandas Set Index +Create index (row label) from existing column or columns. + +You can specify a single column or a comma-separated list of column labels in `column_names`. +If `drop=True`, the specified columns are removed from column labels and become the index. +If `drop=False`, the columns remain in the DataFrame column labels while also being used as the index. +If `append=True`, the new index is added alongside the existing index. + +Below screenshots illustrate these options: + +![Pandas Set Index](../images/set_index1.png) + +![Pandas Set Index](../images/set_index2.png) + +This class internally calls `pandas.DataFrame.set_index()`. + +## Input +| Name | Data type | +|---|---| +| dataframe | DataFrame | +| column_names | String | +| drop | Boolean | +| append | Boolean | + +## Output +| Data type | +|---| +| DataFrame | + +
+Category: Data transformation + +ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved. diff --git a/examples/workflows/dataframe_set_index.json b/examples/workflows/dataframe_set_index.json new file mode 100644 index 0000000..82530b9 --- /dev/null +++ b/examples/workflows/dataframe_set_index.json @@ -0,0 +1 @@ +{"last_node_id":71,"last_link_id":76,"nodes":[{"id":67,"type":"PandasSetIndex","pos":[-388.6587219238281,3272.9404296875],"size":[315,106],"flags":{},"order":5,"mode":0,"inputs":[{"name":"dataframe","type":"DATAFRAME","link":76,"localized_name":"dataframe"}],"outputs":[{"name":"DATAFRAME","type":"DATAFRAME","links":[72],"slot_index":0,"localized_name":"DATAFRAME"}],"properties":{"Node name for S&R":"PandasSetIndex"},"widgets_values":["B",false,true]},{"id":71,"type":"PandasShowDataFrame","pos":[11.976469993591309,3273.62060546875],"size":[210,149.5841064453125],"flags":{},"order":9,"mode":0,"inputs":[{"name":"dataframe","type":"DATAFRAME","link":72,"localized_name":"dataframe"}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6,"localized_name":"STRING"}],"properties":{"Node name for S&R":"PandasShowDataFrame"},"widgets_values":[" A B C\n B \n0 3 1 3 Dog\n1 3 2 3 Cat\n2 3 1 3 Dog\n3 5 1 5 Dog"]},{"id":70,"type":"PandasShowDataFrame","pos":[11.831002235412598,2998.575927734375],"size":[210,149.5841064453125],"flags":{},"order":8,"mode":0,"inputs":[{"name":"dataframe","type":"DATAFRAME","link":71,"localized_name":"dataframe"}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6,"localized_name":"STRING"}],"properties":{"Node name for S&R":"PandasShowDataFrame"},"widgets_values":[" A B C\nB \n3 1 3 Dog\n3 2 3 Cat\n3 1 3 Dog\n5 1 5 Dog"]},{"id":66,"type":"PandasSetIndex","pos":[-390.2712097167969,2999.037109375],"size":[315,106],"flags":{},"order":4,"mode":0,"inputs":[{"name":"dataframe","type":"DATAFRAME","link":75,"localized_name":"dataframe"}],"outputs":[{"name":"DATAFRAME","type":"DATAFRAME","links":[71],"slot_index":0,"localized_name":"DATAFRAME"}],"properties":{"Node name for S&R":"PandasSetIndex"},"widgets_values":["B",false,false]},{"id":64,"type":"PandasSetIndex","pos":[-383.92132568359375,2567.48046875],"size":[315,106],"flags":{},"order":2,"mode":0,"inputs":[{"name":"dataframe","type":"DATAFRAME","link":73,"localized_name":"dataframe"}],"outputs":[{"name":"DATAFRAME","type":"DATAFRAME","links":[69],"slot_index":0,"localized_name":"DATAFRAME"}],"properties":{"Node name for S&R":"PandasSetIndex"},"widgets_values":["B",true,false]},{"id":65,"type":"PandasSetIndex","pos":[-388.32305908203125,2770.81201171875],"size":[315,106],"flags":{},"order":3,"mode":0,"inputs":[{"name":"dataframe","type":"DATAFRAME","link":74,"localized_name":"dataframe"}],"outputs":[{"name":"DATAFRAME","type":"DATAFRAME","links":[70],"slot_index":0,"localized_name":"DATAFRAME"}],"properties":{"Node name for S&R":"PandasSetIndex"},"widgets_values":["B,C",true,false]},{"id":32,"type":"PandasShowDataFrame","pos":[17.071931838989258,2320.961669921875],"size":[210,149.5841064453125],"flags":{},"order":1,"mode":0,"inputs":[{"name":"dataframe","type":"DATAFRAME","link":68,"localized_name":"dataframe"}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6,"localized_name":"STRING"}],"properties":{"Node name for S&R":"PandasShowDataFrame"},"widgets_values":[" A B C\n0 1 3 Dog\n1 2 3 Cat\n2 1 3 Dog\n3 1 5 Dog"]},{"id":69,"type":"PandasShowDataFrame","pos":[21.12071990966797,2769.057861328125],"size":[210,149.5841064453125],"flags":{},"order":7,"mode":0,"inputs":[{"name":"dataframe","type":"DATAFRAME","link":70,"localized_name":"dataframe"}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6,"localized_name":"STRING"}],"properties":{"Node name for S&R":"PandasShowDataFrame"},"widgets_values":[" A\nB C \n3 Dog 1\n Cat 2\n Dog 1\n5 Dog 1"]},{"id":68,"type":"PandasShowDataFrame","pos":[21.334014892578125,2558.572021484375],"size":[210,149.5841064453125],"flags":{},"order":6,"mode":0,"inputs":[{"name":"dataframe","type":"DATAFRAME","link":69,"localized_name":"dataframe"}],"outputs":[{"name":"STRING","type":"STRING","links":null,"shape":6,"localized_name":"STRING"}],"properties":{"Node name for S&R":"PandasShowDataFrame"},"widgets_values":[" A C\nB \n3 1 Dog\n3 2 Cat\n3 1 Dog\n5 1 Dog"]},{"id":63,"type":"PandasCreate","pos":[-765.4253540039062,3112.8271484375],"size":[269.0126953125,149.95111083984375],"flags":{},"order":0,"mode":0,"inputs":[],"outputs":[{"name":"DATAFRAME","type":"DATAFRAME","links":[68,73,74,75,76],"slot_index":0,"localized_name":"DATAFRAME"}],"properties":{"Node name for S&R":"PandasCreate"},"widgets_values":["A,B,C\n1,3,Dog\n2,3,Cat\n1,3,Dog\n1,5,Dog"]}],"links":[[68,63,0,32,0,"DATAFRAME"],[69,64,0,68,0,"DATAFRAME"],[70,65,0,69,0,"DATAFRAME"],[71,66,0,70,0,"DATAFRAME"],[72,67,0,71,0,"DATAFRAME"],[73,63,0,64,0,"DATAFRAME"],[74,63,0,65,0,"DATAFRAME"],[75,63,0,66,0,"DATAFRAME"],[76,63,0,67,0,"DATAFRAME"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.7513148009015777,"offset":[1187.8497396282603,-2561.5360860733363]},"node_versions":{"data-analysis":"9a7ca3b04d3bb2f188c14805edd54af3290271a0"},"ue_links":[]},"version":0.4} \ No newline at end of file diff --git a/modules/pandas_wrapper/pandas_set_index.py b/modules/pandas_wrapper/pandas_set_index.py new file mode 100644 index 0000000..e3ed1ed --- /dev/null +++ b/modules/pandas_wrapper/pandas_set_index.py @@ -0,0 +1,70 @@ +from typing import Any, Dict +from io import StringIO +import pandas as pd + +class PandasSetIndex: + """ + Create index (row label) from existing column or columns. + + You can specify a single column or a comma-separated list of column labels in `column_names`. + If `drop=True`, the specified columns are removed from column labels and become the index. + If `drop=False`, the columns remain in the DataFrame column labels while also being used as the index. + If `append=True`, the new index is added alongside the existing index. + + Below screenshots illustrate these options: + + ![Pandas Set Index](../images/set_index1.png) + + ![Pandas Set Index](../images/set_index2.png) + + This class internally calls `pandas.DataFrame.set_index()`. + + category: Data 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_names": ("STRING", {"default": ""}), + "drop": ("BOOLEAN", {"default": True}), + "append": ("BOOLEAN", {"default": False}) + } + } + + RETURN_TYPES: tuple = ("DATAFRAME",) + FUNCTION: str = "f" + CATEGORY: str = "Data Analysis" + + def f(self, dataframe: pd.DataFrame, column_names: str, drop: bool, append: bool) -> tuple: + """ + Create index (row label) from existing column or columns. + + Args: + dataframe (DataFrame): The DataFrame. + column_names (str): A single column label or a comma-separated string of column names to select. + drop (bool): If `drop=True`, the specified columns are removed from column labels and become the index. + If `drop=False`, the columns remain in the DataFrame column labels while also being used as the index. + append (bool): If `append=True`, the new index is added alongside the existing index. + + Returns: + tuple: A tuple containing the DataFrame. + """ + columns = [col.strip() for col in column_names.split(",")] + for c in columns: + if c not in dataframe.columns: + raise ValueError(f"Invalid column name {c}") + if len(columns) > 1: + arg = columns + else: + arg = columns[0] + + df2 = dataframe.set_index(arg, drop=drop, append=append) + return (df2,) diff --git a/pyproject.toml b/pyproject.toml index 623a5d7..8ca92e3 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.14" +version = "1.1.15" license = {file = "LICENSE"} [project.urls]