Added Pandas Load JSON and Pandas Save JSON nodes.
This commit is contained in:
@@ -15,9 +15,11 @@ from .modules.pandas_wrapper.pandas_join import PandasJoin
|
||||
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
|
||||
from .modules.pandas_wrapper.pandas_load_json import PandasLoadJSON
|
||||
from .modules.pandas_wrapper.pandas_loc_cell_str import PandasLocCellStr
|
||||
from .modules.pandas_wrapper.pandas_loc_row_series import PandasLocRowSeries
|
||||
from .modules.pandas_wrapper.pandas_save_csv import PandasSaveCSV
|
||||
from .modules.pandas_wrapper.pandas_save_json import PandasSaveJSON
|
||||
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_string import PandasSeriesToString
|
||||
@@ -46,9 +48,11 @@ NODE_CLASS_MAPPINGS: Dict[str, Type[T]] = {
|
||||
"PandasLoadCSV": PandasLoadCSV,
|
||||
"PandasLoadCSVWithEncoding": PandasLoadCSVWithEncoding,
|
||||
"PandasLoadCSVWithIndex": PandasLoadCSVWithIndex,
|
||||
"PandasLoadJSON": PandasLoadJSON,
|
||||
"PandasLocCellStr": PandasLocCellStr,
|
||||
"PandasLocRowSeries": PandasLocRowSeries,
|
||||
"PandasSaveCSV": PandasSaveCSV,
|
||||
"PandasSaveJSON": PandasSaveJSON,
|
||||
"PandasSelectColumns": PandasSelectColumns,
|
||||
"PandasSelectRows": PandasSelectRows,
|
||||
"PandasSeriesToString": PandasSeriesToString,
|
||||
@@ -80,9 +84,11 @@ NODE_DISPLAY_NAME_MAPPINGS: Dict[str, str] = {
|
||||
"PandasLoadCSV": "Pandas Load CSV",
|
||||
"PandasLoadCSVWithEncoding": "Pandas Load CSV With Encoding",
|
||||
"PandasLoadCSVWithIndex": "Pandas Load CSV With Index",
|
||||
"PandasLoadJSON": "Pandas Load JSON",
|
||||
"PandasLocCellStr": "Pandas Loc Cell Str",
|
||||
"PandasLocRowSeries": "Pandas Loc Row Series",
|
||||
"PandasSaveCSV": "Pandas Save CSV",
|
||||
"PandasSaveJSON": "Pandas Save JSON",
|
||||
"PandasSelectColumns": "Pandas Select Columns",
|
||||
"PandasSelectRows": "Pandas Select Rows",
|
||||
"PandasSeriesToString": "Pandas Series To String",
|
||||
|
||||
@@ -18,7 +18,9 @@ You can right-click, select **Add Node**, go to **Data Analysis**, and look for
|
||||
| **Pandas Load CSV** | Load a CSV file |
|
||||
| **Pandas Load CSV With Encoding** | Load a CSV file not encoded in utf-8 |
|
||||
| **Pandas Load CSV With Index** | Load a CSV file containing index |
|
||||
| **Pandas Load JSON** | Load a JSON file |
|
||||
| **Pandas Save CSV** | Save a DataFrame to a CSV file |
|
||||
| **Pandas Save JSON** | Save a DataFrame to a JSON file |
|
||||
| **Pandas Create** | Create a DataFrame from CSV text field |
|
||||
| **Pandas Create With Index** | Create a DataFrame from CSV text field containing index |
|
||||
| **CDA JSON Create** | Create JSON from a string entered in a text field |
|
||||
@@ -71,11 +73,14 @@ The examples directory contains workflows that load data from an example dataset
|
||||
Use **Pandas Load CSV** node to load a CSV, or **Pandas Load CSV With Index** node if the CSV contains an index column. These nodes assume that the file is encoded in utf-8. If the file is not encoded in utf-8, use **Pandas Load CSV With Encoding** to specify the encoding of the file. This is necessary if the data was collected before utf-8 encoding became popular. For example, you can try "latin_1" for a file that contains accented characters in the US and Western Europe.
|
||||

|
||||
|
||||
Use **Pandas Load JSON** node to load a JSON file.
|
||||
|
||||
These nodes emit the DataFrame in a JSON string.
|
||||
CSV file path is relative to the ComfyUI installation directory unless you specify the absolute file path.
|
||||
|
||||
## Saving data
|
||||
Use **Pandas Save CSV** node to save the DataFrame to a CSV file.
|
||||
Use **Pandas Save JSON** node to save the DataFrame to a JSON file.
|
||||
|
||||
## Creating data on the UI
|
||||
To construct a DataFrame on the UI, use **Pandas Create** or **Pandas Create with Index** nodes. These nodes display the multiline text area where you can enter the data in CSV format.
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
from typing import Any, Dict
|
||||
from io import StringIO
|
||||
import pandas as pd
|
||||
|
||||
|
||||
class PandasLoadJSON:
|
||||
"""
|
||||
PandasLoadJSON:
|
||||
A class for loading JSON files into a pandas DataFrame.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls) -> Dict[str, Any]:
|
||||
"""
|
||||
Defines the input types for the `load_json` function.
|
||||
|
||||
Returns:
|
||||
Dict[str, Any]: A dictionary specifying required input types.
|
||||
"""
|
||||
return {
|
||||
"required": {
|
||||
"file_path": ("STRING", {"multiline": False}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES: tuple = ("STRING",)
|
||||
FUNCTION: str = "load_json"
|
||||
CATEGORY: str = "Data Analysis"
|
||||
|
||||
def load_json(self, file_path: str) -> tuple:
|
||||
"""
|
||||
Loads a JSON file into a pandas DataFrame and converts it to a JSON string.
|
||||
|
||||
Args:
|
||||
file_path (str): The path to the JSON file.
|
||||
|
||||
Returns:
|
||||
tuple: A tuple containing a JSON string representation of the DataFrame.
|
||||
"""
|
||||
# Read JSON file into DataFrame
|
||||
df = pd.read_json(file_path)
|
||||
|
||||
# Convert DataFrame to JSON
|
||||
result_json = df.to_json()
|
||||
|
||||
return (result_json,)
|
||||
@@ -0,0 +1,63 @@
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
from typing import Any, Dict
|
||||
from io import StringIO
|
||||
import pandas as pd
|
||||
|
||||
class PandasSaveJSON:
|
||||
"""
|
||||
PandasSaveJSON:
|
||||
A class for saving a PandasDataFrame to a JSON file.
|
||||
"""
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {
|
||||
"required": {
|
||||
"dataframe_json": ("STRING", {"forceInput": True}),
|
||||
"file_path": ("STRING", {"multiline": False})
|
||||
},
|
||||
"hidden": {
|
||||
"unique_id": "UNIQUE_ID",
|
||||
"extra_pnginfo": "EXTRA_PNGINFO",
|
||||
},
|
||||
}
|
||||
|
||||
INPUT_IS_LIST = True
|
||||
RETURN_TYPES = ("STRING",)
|
||||
FUNCTION = "save_json"
|
||||
OUTPUT_NODE = True
|
||||
OUTPUT_IS_LIST = (True,)
|
||||
|
||||
CATEGORY = "Data Analysis"
|
||||
|
||||
def save_json(self, dataframe_json,file_path=None, 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")
|
||||
elif file_path is None or len(file_path) == 0:
|
||||
print("Error: file path is not specified")
|
||||
else:
|
||||
# Deserialize JSON string to DataFrame
|
||||
df = pd.read_json(StringIO(dataframe_json[0]))
|
||||
df.to_json(path_or_buf=file_path[0]) # Save as JSON
|
||||
text = [str(df)] # 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,)}
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
[project]
|
||||
name = "data-analysis"
|
||||
description = "Data analysis custom modules for ComfyUI - Use Pandas & Matplotlib within ComfyUI"
|
||||
version = "1.0.16"
|
||||
version = "1.0.17"
|
||||
license = {file = "LICENSE"}
|
||||
|
||||
[project.urls]
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
This code is based on
|
||||
https://github.com/pythongosssss/ComfyUI-Custom-Scripts/blob/main/web/js/showText.js
|
||||
|
||||
See credit/credit.md for the full license.
|
||||
*/
|
||||
|
||||
import { app } from "../../../scripts/app.js";
|
||||
import { ComfyWidgets } from "../../../scripts/widgets.js";
|
||||
|
||||
// Displays input text on a node
|
||||
app.registerExtension({
|
||||
name: "HowToSD.SaveJSON",
|
||||
async beforeRegisterNodeDef(nodeType, nodeData, app) {
|
||||
if (nodeData.name === "PandasSaveJSON") { // This needs to match NODE_CLASS_MAPPINGS in Python
|
||||
function populate(text) {
|
||||
// No op as we are not updating the node's UI for now.
|
||||
}
|
||||
|
||||
// When the node is executed we will be sent the input text, display this in the widget
|
||||
const onExecuted = nodeType.prototype.onExecuted;
|
||||
nodeType.prototype.onExecuted = function (message) {
|
||||
onExecuted?.apply(this, arguments);
|
||||
populate.call(this, message.text);
|
||||
};
|
||||
|
||||
const onConfigure = nodeType.prototype.onConfigure;
|
||||
nodeType.prototype.onConfigure = function () {
|
||||
onConfigure?.apply(this, arguments);
|
||||
if (this.widgets_values?.length) {
|
||||
populate.call(this, this.widgets_values.slice(+this.widgets_values.length > 1));
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user