Added Numpy Show, Numpy Squeeze, Pandas Feature Split To Numpy, Pt Show Size nodes.
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
"""
|
||||
This code is based on
|
||||
https://github.com/pythongosssss/ComfyUI-Custom-Scripts/blob/main/py/show_text.py
|
||||
|
||||
See credit/credit.md for the full license.
|
||||
"""
|
||||
import numpy as np
|
||||
|
||||
class NumpyShow:
|
||||
"""
|
||||
Displays a Numpy ndarray as text.
|
||||
|
||||
category: Numpy
|
||||
"""
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {
|
||||
"required": {
|
||||
"ndarray": ("NDARRAY", {}),
|
||||
},
|
||||
"hidden": {
|
||||
"unique_id": "UNIQUE_ID",
|
||||
"extra_pnginfo": "EXTRA_PNGINFO",
|
||||
},
|
||||
}
|
||||
|
||||
INPUT_IS_LIST = True
|
||||
RETURN_TYPES = ("STRING",)
|
||||
FUNCTION = "notify"
|
||||
OUTPUT_NODE = True
|
||||
OUTPUT_IS_LIST = (True,)
|
||||
|
||||
CATEGORY = "Data Analysis"
|
||||
|
||||
def notify(self, ndarray, unique_id=None, extra_pnginfo=None):
|
||||
text = None
|
||||
if unique_id is not None and extra_pnginfo is not None:
|
||||
if not isinstance(extra_pnginfo, list):
|
||||
print("Error: extra_pnginfo is not a list")
|
||||
elif (
|
||||
not isinstance(extra_pnginfo[0], dict)
|
||||
or "workflow" not in extra_pnginfo[0]
|
||||
):
|
||||
print("Error: extra_pnginfo[0] is not a dict or missing 'workflow' key")
|
||||
else:
|
||||
ind = ndarray[0]
|
||||
text = [str(ind)] # wrap in list
|
||||
workflow = extra_pnginfo[0]["workflow"]
|
||||
node = next(
|
||||
(x for x in workflow["nodes"] if str(x["id"]) == str(unique_id[0])),
|
||||
None,
|
||||
)
|
||||
if node:
|
||||
node["widgets_values"] = [text]
|
||||
else:
|
||||
print("unique_id or extra_pnginfo is None.")
|
||||
return {"ui": {"text": text}, "result": (text,)}
|
||||
@@ -0,0 +1,45 @@
|
||||
from typing import Any, Dict
|
||||
import numpy as np
|
||||
|
||||
|
||||
class NumpySqueeze:
|
||||
"""
|
||||
Removes a dimension at the specified position in the input array if it is of size 1.
|
||||
|
||||
Specifying a tuple of dimensions is not supported.
|
||||
|
||||
category: Numpy
|
||||
"""
|
||||
|
||||
@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": {
|
||||
"array": ("NDARRAY", {}),
|
||||
"dim": ("INT", {"default": -1, "min": -1, "max": 10})
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES: tuple = ("NDARRAY",)
|
||||
FUNCTION: str = "f"
|
||||
CATEGORY: str = "Data Analysis"
|
||||
|
||||
def f(self, array: np.ndarray, dim: int) -> tuple:
|
||||
"""
|
||||
Removes a dimension at the specified position in the input array if it is of size 1.
|
||||
|
||||
Args:
|
||||
array (np.ndarray): Input array.
|
||||
dim (int): Dimension to remove if it is of size 1.
|
||||
|
||||
Returns:
|
||||
tuple: A tuple containing the transformed NumPy array.
|
||||
"""
|
||||
ar_out = np.squeeze(array, dim)
|
||||
return (ar_out,)
|
||||
@@ -0,0 +1,71 @@
|
||||
from typing import Any, Dict
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
|
||||
class PandasFeatureSplitToNumpy:
|
||||
"""
|
||||
Splits a Pandas DataFrame into feature Numpy ndarray and label Numpy ndarray.
|
||||
If output_1d_label is set, label will be output as a 1d array instead of a 2d array.
|
||||
|
||||
As shown in the below screenshot, this node can replace multiple nodes that are used to split Pandas DataFrame into two DataFrames, convert to NumPy, then squeeze the label data.
|
||||

|
||||
|
||||
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", {}),
|
||||
"label_integer_position": ("INT", {"default": -1, "min": -10, "max": 1024}),
|
||||
"output_1d_label": ("BOOLEAN", {"default": True})
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES: tuple = ("NDARRAY", "NDARRAY")
|
||||
RETURN_NAMES: tuple = ("feature", "label")
|
||||
|
||||
FUNCTION: str = "f"
|
||||
CATEGORY: str = "Data Analysis"
|
||||
|
||||
def f(self, dataframe: pd.DataFrame,
|
||||
label_integer_position: int,
|
||||
output_1d_label: bool) -> tuple:
|
||||
"""
|
||||
Splits a Pandas DataFrame into feature Numpy ndarray and label Numpy ndarray.
|
||||
|
||||
Args:
|
||||
dataframe (pd.DataFrame): The DataFrame to split.
|
||||
label_integer_position (int): The column integer position of the label.
|
||||
output_1d_label (bool): If output_1d_label is set, label will be output as a 1d array instead of a 2d array.
|
||||
|
||||
Returns:
|
||||
tuple: A tuple containing the feature and label arrays.
|
||||
"""
|
||||
num_columns = dataframe.shape[1]
|
||||
|
||||
if label_integer_position < 0:
|
||||
label_integer_position += num_columns
|
||||
|
||||
# Validate label_integer_position
|
||||
if label_integer_position >= num_columns:
|
||||
raise ValueError(f"label_integer_position {label_integer_position} is out of range for dataframe with {num_columns} columns.")
|
||||
|
||||
# Extract features
|
||||
np_left = dataframe.iloc[:, :label_integer_position].to_numpy()
|
||||
np_right = dataframe.iloc[:, label_integer_position + 1:].to_numpy() if label_integer_position < num_columns - 1 else np.empty((len(dataframe), 0))
|
||||
np_features = np.hstack([np_left, np_right]) if np_right.shape[1] > 0 else np_left
|
||||
|
||||
# Extract label
|
||||
np_label = dataframe.iloc[:, label_integer_position].to_numpy()
|
||||
if output_1d_label:
|
||||
np_label = np_label.ravel()
|
||||
|
||||
return (np_features, np_label)
|
||||
@@ -0,0 +1,60 @@
|
||||
"""
|
||||
Almost all of this code was taken from
|
||||
https://github.com/pythongosssss/ComfyUI-Custom-Scripts/blob/main/py/show_text.py
|
||||
|
||||
See credit/credit.md for the full license.
|
||||
"""
|
||||
from typing import List
|
||||
import torch
|
||||
|
||||
|
||||
class PtShowSize:
|
||||
"""
|
||||
Displays PyTorch Size object as a string.
|
||||
|
||||
category: Display data
|
||||
"""
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {
|
||||
"required": {
|
||||
"size": ("PTSIZE", {}),
|
||||
},
|
||||
"hidden": {
|
||||
"unique_id": "UNIQUE_ID",
|
||||
"extra_pnginfo": "EXTRA_PNGINFO",
|
||||
},
|
||||
}
|
||||
|
||||
INPUT_IS_LIST = True
|
||||
RETURN_TYPES = ("STRING",)
|
||||
FUNCTION = "notify"
|
||||
OUTPUT_NODE = True
|
||||
OUTPUT_IS_LIST = (True,)
|
||||
|
||||
CATEGORY = "Data Analysis"
|
||||
|
||||
MAX_NUM_ELEMENTS_TO_DISPLAY = 100
|
||||
|
||||
def notify(self, size: torch.Size, unique_id=None, extra_pnginfo=None):
|
||||
text = str(size[0])
|
||||
|
||||
if unique_id is not None and extra_pnginfo is not None:
|
||||
if not isinstance(extra_pnginfo, list):
|
||||
print("Error: extra_pnginfo is not a list")
|
||||
elif (
|
||||
not isinstance(extra_pnginfo[0], dict)
|
||||
or "workflow" not in extra_pnginfo[0]
|
||||
):
|
||||
print("Error: extra_pnginfo[0] is not a dict or missing 'workflow' key")
|
||||
else:
|
||||
workflow = extra_pnginfo[0]["workflow"]
|
||||
node = next(
|
||||
(x for x in workflow["nodes"] if str(x["id"]) == str(unique_id[0])),
|
||||
None,
|
||||
)
|
||||
if node:
|
||||
node["widgets_values"] = [text]
|
||||
else:
|
||||
print("unique_id or extra_pnginfo is None.")
|
||||
return {"ui": {"text": [text]}, "result": ([text],)}
|
||||
Reference in New Issue
Block a user