Last active
December 9, 2024 16:54
-
-
Save vincentqb/bc3f7df0bfd2d279237f2d11525a12f8 to your computer and use it in GitHub Desktop.
Simple Metric Logger in Python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import socket | |
| import pandas as pd | |
| class MetricLogger: | |
| def __init__(self, root="runs"): | |
| self.metrics = {} | |
| self.iteration = 0 | |
| current = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") | |
| hostname = socket.gethostname() | |
| self.path = Path(f"{root}/{current}_{hostname}/metrics.csv") | |
| self.path.parent.mkdir(parents=True, exist_ok=True) | |
| def __setitem__(self, key, value): | |
| self.metrics[key] = self.metrics.get(key, {}) | |
| self.iteration = max(len(self.metrics[key]), self.iteration) | |
| self.metrics[key][self.iteration] = value | |
| def __getitem__(self, key): | |
| return self.metrics.get(key, {}).values() | |
| def update(self, prefix, d): | |
| for k, v in d.items(): | |
| self[f"{prefix}_{k}"] = v | |
| def to_dataframe(self): | |
| return pd.DataFrame(self.metrics) | |
| def __repr__(self): | |
| return self.to_dataframe().to_string(index=False, na_rep="") | |
| def save(self): | |
| self.to_dataframe().to_csv(self.path, sep="|", index=False, mode='a', header=not self.path.exists()) | |
| @staticmethod | |
| def read(path): | |
| csv = pd.read_csv(path, sep="|") | |
| # keep nulls: csv = csv.to_dict() | |
| # drop nulls: csv = {name: {k: v for k, v in column.items() if pd.notnull(v)} for name, column in csv.to_dict().items()} | |
| return csv | |
| def __enter__(self): | |
| return self | |
| def __exit__(self, exc_type, exc_val, exc_tb): | |
| self.save() | |
| if __name__ == "__main__": | |
| with MetricLogger() as logger: | |
| logger["a"] = 0 | |
| logger["b"] = 1 | |
| logger["a"] = 2 | |
| logger["c"] = 3 | |
| logger["a"] = 4 | |
| print(logger) | |
| # a b c | |
| # 0 1.0 | |
| # 2 3.0 | |
| # 4 |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To avoid the lists from becoming too big, they may need to be dumped once in a while.
https://stackoverflow.com/questions/50066619/python-non-blocking-write-csv-file
https://stackoverflow.com/questions/48263704/threadpoolexecutor-how-to-limit-the-queue-maxsize