Repository: aeon-toolkit/aeon
Pull request #1401 (2024-04-11 13:21:54)

[DOC] Adds previously implemented classifiers to docs/api_references
<!--
Thanks for contributing a pull request! Please ensure you have taken a look at our
contribution guide: https://www.aeon-toolkit.org/en/stable/contributing.html

Feel free to delete sections of this template if they do not apply to your PR,
avoid submitting a blank template or empty sections.
-->

#### What does this implement/fix? Explain your changes.

<!--
A clear and concise description of what you have implemented.
-->

Assuming the updates to docs/api_reference were done in error, these changes add entries for classifiers implemented in the following PRs:
- https://github.com/aeon-toolkit/aeon/pull/1221
- https://github.com/aeon-toolkit/aeon/pull/1173

#### Any other comments?

I didn't do an exhaustive search for implemented classifiers that aren't in the API reference, so there may be some greatness that's still (relatively) hard to discover.
 
### PR checklist

<!--
Please go through the checklist below. Please feel free to remove points if they are not applicable.
-->

##### For all contributions
- [x] I've added myself to the [list of contributors](https://github.com/aeon-toolkit/aeon/blob/main/.all-contributorsrc). Alternatively, you can use the [@all-contributors](https://allcontributors.org/docs/en/bot/usage) bot to do this for you.
- [x] The PR title starts with either [ENH], [MNT], [DOC], [BUG], [REF], [DEP] or [GOV] indicating whether the PR topic is related to enhancement, maintenance, documentation, bugs, refactoring, deprecation or governance.

<!--
Thanks for contributing!
-->


aeon-actions-bot[bot]: 
## Thank you for contributing to `aeon`

I have added the following labels to this PR based on the title: **[ $\\color{#F3B9F8}{\\textsf{documentation}}$ ]**.


The [Checks](https://github.com/aeon-toolkit/aeon/pull/1401/checks) tab will show the status of our automated tests. You can click on individual test runs in the tab or "Details" in the panel below to see more information if there is a failure.

If our `pre-commit` code quality check fails, any trivial fixes will automatically be pushed to your PR unless it is a draft.

Don't hesitate to ask questions on the `aeon` [Slack](
https://join.slack.com/t/aeon-toolkit/shared_invite/zt-22vwvut29-HDpCu~7VBUozyfL_8j3dLA) channel if you have any.
    

Patch:
diff --git a/.all-contributorsrc b/.all-contributorsrc
index abc24f43..ce7d77cd 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -168,11 +168,17 @@
         "doc",
         "design",
         "example",
+        "ideas",
         "infra",
         "maintenance",
+        "mentoring",
+        "promotion",
+        "question",
+        "research",
+        "review",
         "test",
         "tutorial",
-        "review"
+        "talk"
       ]
     },
     {
@@ -2372,6 +2378,15 @@
       "contributions": [
         "bug"
       ]
+    },
+    {
+      "login": "wayneadams",
+      "name": "Wayne Adams",
+      "avatar_url": "https://avatars.githubusercontent.com/u/15034841?v=4",
+      "profile": "https://github.com/wayneadams",
+      "contributions": [
+        "doc"
+      ]
     }
   ],
   "commitType": "docs"
diff --git a/.github/workflows/github_maintenace.yml b/.github/workflows/github_maintenace.yml
new file mode 100644
index 00000000..3a483385
--- /dev/null
+++ b/.github/workflows/github_maintenace.yml
@@ -0,0 +1,35 @@
+name: GitHub Maintenance
+
+on:
+  schedule:
+    # every Monday at 01:00 AM UTC
+    - cron:  "0 1 * * 1"
+  workflow_dispatch:
+
+permissions:
+  issues: write
+  contents: write
+
+jobs:
+  stale_branches:
+    runs-on: ubuntu-20.04
+
+    steps:
+      - name: Create app token
+        uses: actions/create-github-app-token@v1
+        id: app-token
+        with:
+          app-id: ${{ vars.PR_APP_ID }}
+          private-key: ${{ secrets.PR_APP_KEY }}
+
+      - name: Stale Branches
+        uses: crs-k/stale-branches@v4.1.0
+        with:
+          repo-token: ${{ steps.app-token.outputs.token }}
+          days-before-stale: 140
+          days-before-delete: 9999  # todo take down to 175
+          comment-updates: true
+          tag-committer: true
+          stale-branch-label: "stale"
+          compare-branches: 'info'
+          pr-check: true
diff --git a/.github/workflows/pr_examples.yml b/.github/workflows/pr_examples.yml
index 53367fb8..905553c4 100644
--- a/.github/workflows/pr_examples.yml
+++ b/.github/workflows/pr_examples.yml
@@ -45,5 +45,5 @@ jobs:
           command: python -m pip install .[all_extras,binder,dev]
 
       - name: Run example notebooks
-        run: build_tools/run_examples.sh
+        run: build_tools/run_examples.sh ${{ github.event_name != 'pull_request' || !contains(github.event.pull_request.labels.*.name, 'full examples run') }}
         shell: bash
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 4ec569f7..c7ff4fc1 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -1,7 +1,7 @@
 # Contributors
 
 <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
-[![All Contributors](https://img.shields.io/badge/all_contributors-230-orange.svg)](#contributors)
+[![All Contributors](https://img.shields.io/badge/all_contributors-231-orange.svg)](#contributors)
 <!-- ALL-CONTRIBUTORS-BADGE:END -->
 
 This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
@@ -166,7 +166,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
     <tr>
       <td align="center" valign="top" width="12.5%"><a href="https://www.linkedin.com/in/martin-walter-1a33b3114/"><img src="https://avatars0.githubusercontent.com/u/29627036?v=4?s=80" width="80px;" alt="Martin Walter"/><br /><sub><b>Martin Walter</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=aiwalter" title="Code">💻</a> <a href="https://github.com/aeon-toolkit/aeon/issues?q=author%3Aaiwalter" title="Bug reports">🐛</a> <a href="#projectManagement-aiwalter" title="Project Management">📆</a> <a href="#fundingFinding-aiwalter" title="Funding Finding">🔍</a> <a href="#mentoring-aiwalter" title="Mentoring">🧑‍🏫</a> <a href="#ideas-aiwalter" title="Ideas, Planning, & Feedback">🤔</a> <a href="#design-aiwalter" title="Design">🎨</a> <a href="https://github.com/aeon-toolkit/aeon/pulls?q=is%3Apr+reviewed-by%3Aaiwalter" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=aiwalter" title="Documentation">📖</a> <a href="#talk-aiwalter" title="Talks">📢</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/martinagvilas"><img src="https://avatars2.githubusercontent.com/u/37339384?v=4?s=80" width="80px;" alt="Martina G. Vilas"/><br /><sub><b>Martina G. Vilas</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/pulls?q=is%3Apr+reviewed-by%3Amartinagvilas" title="Reviewed Pull Requests">👀</a> <a href="#ideas-martinagvilas" title="Ideas, Planning, & Feedback">🤔</a></td>
-      <td align="center" valign="top" width="12.5%"><a href="https://github.com/MatthewMiddlehurst"><img src="https://avatars0.githubusercontent.com/u/25731235?v=4?s=80" width="80px;" alt="Matthew Middlehurst"/><br /><sub><b>Matthew Middlehurst</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/issues?q=author%3AMatthewMiddlehurst" title="Bug reports">🐛</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=MatthewMiddlehurst" title="Code">💻</a> <a href="#data-MatthewMiddlehurst" title="Data">🔣</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=MatthewMiddlehurst" title="Documentation">📖</a> <a href="#design-MatthewMiddlehurst" title="Design">🎨</a> <a href="#example-MatthewMiddlehurst" title="Examples">💡</a> <a href="#infra-MatthewMiddlehurst" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#maintenance-MatthewMiddlehurst" title="Maintenance">🚧</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=MatthewMiddlehurst" title="Tests">⚠️</a> <a href="#tutorial-MatthewMiddlehurst" title="Tutorials">✅</a> <a href="https://github.com/aeon-toolkit/aeon/pulls?q=is%3Apr+reviewed-by%3AMatthewMiddlehurst" title="Reviewed Pull Requests">👀</a></td>
+      <td align="center" valign="top" width="12.5%"><a href="https://github.com/MatthewMiddlehurst"><img src="https://avatars0.githubusercontent.com/u/25731235?v=4?s=80" width="80px;" alt="Matthew Middlehurst"/><br /><sub><b>Matthew Middlehurst</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/issues?q=author%3AMatthewMiddlehurst" title="Bug reports">🐛</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=MatthewMiddlehurst" title="Code">💻</a> <a href="#data-MatthewMiddlehurst" title="Data">🔣</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=MatthewMiddlehurst" title="Documentation">📖</a> <a href="#design-MatthewMiddlehurst" title="Design">🎨</a> <a href="#example-MatthewMiddlehurst" title="Examples">💡</a> <a href="#ideas-MatthewMiddlehurst" title="Ideas, Planning, & Feedback">🤔</a> <a href="#infra-MatthewMiddlehurst" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#maintenance-MatthewMiddlehurst" title="Maintenance">🚧</a> <a href="#mentoring-MatthewMiddlehurst" title="Mentoring">🧑‍🏫</a> <a href="#promotion-MatthewMiddlehurst" title="Promotion">📣</a> <a href="#question-MatthewMiddlehurst" title="Answering Questions">💬</a> <a href="#research-MatthewMiddlehurst" title="Research">🔬</a> <a href="https://github.com/aeon-toolkit/aeon/pulls?q=is%3Apr+reviewed-by%3AMatthewMiddlehurst" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=MatthewMiddlehurst" title="Tests">⚠️</a> <a href="#tutorial-MatthewMiddlehurst" title="Tutorials">✅</a> <a href="#talk-MatthewMiddlehurst" title="Talks">📢</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/solen0id"><img src="https://avatars.githubusercontent.com/u/20767606?v=4?s=80" width="80px;" alt="Max Patzelt"/><br /><sub><b>Max Patzelt</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=solen0id" title="Code">💻</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/Hephaest"><img src="https://avatars2.githubusercontent.com/u/37981444?v=4?s=80" width="80px;" alt="Miao Cai"/><br /><sub><b>Miao Cai</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/issues?q=author%3AHephaest" title="Bug reports">🐛</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=Hephaest" title="Code">💻</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/frankl1"><img src="https://avatars.githubusercontent.com/u/23366578?s=96&v=4?s=80" width="80px;" alt="Michael F. Mbouopda"/><br /><sub><b>Michael F. Mbouopda</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=frankl1" title="Code">💻</a> <a href="https://github.com/aeon-toolkit/aeon/issues?q=author%3Afrankl1" title="Bug reports">🐛</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=frankl1" title="Documentation">📖</a></td>
@@ -251,9 +251,10 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/victordremov"><img src="https://avatars.githubusercontent.com/u/32140716?s=80" width="80px;" alt="Viktor Dremov"/><br /><sub><b>Viktor Dremov</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=victordremov" title="Code">💻</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/ViktorKaz"><img src="https://avatars0.githubusercontent.com/u/33499138?v=4?s=80" width="80px;" alt="ViktorKaz"/><br /><sub><b>ViktorKaz</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=ViktorKaz" title="Code">💻</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=ViktorKaz" title="Documentation">📖</a> <a href="#design-ViktorKaz" title="Design">🎨</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/VyomkeshVyas"><img src="https://avatars.githubusercontent.com/u/110027694?v=4?s=80" width="80px;" alt="Vyomkesh Vyas"/><br /><sub><b>Vyomkesh Vyas</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=VyomkeshVyas" title="Code">💻</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=VyomkeshVyas" title="Documentation">📖</a> <a href="#example-VyomkeshVyas" title="Examples">💡</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=VyomkeshVyas" title="Tests">⚠️</a></td>
-      <td align="center" valign="top" width="12.5%"><a href="https://www.linkedin.com/in/templierw/"><img src="https://github.com/templierw.png?s=80" width="80px;" alt="William Templier"/><br /><sub><b>William Templier</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=templierw" title="Documentation">📖</a></td>
+      <td align="center" valign="top" width="12.5%"><a href="https://github.com/wayneadams"><img src="https://avatars.githubusercontent.com/u/15034841?v=4?s=80" width="80px;" alt="Wayne Adams"/><br /><sub><b>Wayne Adams</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=wayneadams" title="Documentation">📖</a></td>
     </tr>
     <tr>
+      <td align="center" valign="top" width="12.5%"><a href="https://www.linkedin.com/in/templierw/"><img src="https://github.com/templierw.png?s=80" width="80px;" alt="William Templier"/><br /><sub><b>William Templier</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=templierw" title="Documentation">📖</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/wwzeng1"><img src="https://avatars.githubusercontent.com/u/44910023?v=4?s=80" width="80px;" alt="William Zeng"/><br /><sub><b>William Zeng</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/issues?q=author%3Awwzeng1" title="Bug reports">🐛</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/magittan"><img src="https://avatars0.githubusercontent.com/u/14024202?v=4?s=80" width="80px;" alt="William Zheng"/><br /><sub><b>William Zheng</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=magittan" title="Code">💻</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=magittan" title="Tests">⚠️</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/yairbeer"><img src="https://avatars.githubusercontent.com/yairbeer?s=80" width="80px;" alt="Yair Beer"/><br /><sub><b>Yair Beer</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=yairbeer" title="Code">💻</a></td>
@@ -261,9 +262,9 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/xuyxu"><img src="https://avatars2.githubusercontent.com/u/22359569?v=4?s=80" width="80px;" alt="Yi-Xuan Xu"/><br /><sub><b>Yi-Xuan Xu</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=xuyxu" title="Code">💻</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=xuyxu" title="Tests">⚠️</a> <a href="#maintenance-xuyxu" title="Maintenance">🚧</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=xuyxu" title="Documentation">📖</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/ZiyaoWei"><img src="https://avatars.githubusercontent.com/u/940823?v=4?s=80" width="80px;" alt="Ziyao Wei"/><br /><sub><b>Ziyao Wei</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=ZiyaoWei" title="Code">💻</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/aa25desh"><img src="https://avatars1.githubusercontent.com/u/29518290?v=4?s=80" width="80px;" alt="aa25desh"/><br /><sub><b>aa25desh</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=aa25desh" title="Code">💻</a> <a href="https://github.com/aeon-toolkit/aeon/issues?q=author%3Aaa25desh" title="Bug reports">🐛</a></td>
-      <td align="center" valign="top" width="12.5%"><a href="https://github.com/abandus"><img src="https://avatars2.githubusercontent.com/u/46486474?v=4?s=80" width="80px;" alt="abandus"/><br /><sub><b>abandus</b></sub></a><br /><a href="#ideas-abandus" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=abandus" title="Code">💻</a></td>
     </tr>
     <tr>
+      <td align="center" valign="top" width="12.5%"><a href="https://github.com/abandus"><img src="https://avatars2.githubusercontent.com/u/46486474?v=4?s=80" width="80px;" alt="abandus"/><br /><sub><b>abandus</b></sub></a><br /><a href="#ideas-abandus" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=abandus" title="Code">💻</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/adoherty21"><img src="https://avatars.githubusercontent.com/u/52799751?s=400&v=4?s=80" width="80px;" alt="adoherty21"/><br /><sub><b>adoherty21</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/issues?q=author%3Aadoherty21" title="Bug reports">🐛</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/bethrice44"><img src="https://avatars.githubusercontent.com/u/11226988?v=4?s=80" width="80px;" alt="bethrice44"/><br /><sub><b>bethrice44</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/issues?q=author%3Abethrice44" title="Bug reports">🐛</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=bethrice44" title="Code">💻</a> <a href="https://github.com/aeon-toolkit/aeon/pulls?q=is%3Apr+reviewed-by%3Abethrice44" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=bethrice44" title="Tests">⚠️</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/big-o"><img src="https://avatars1.githubusercontent.com/u/1134151?v=4?s=80" width="80px;" alt="big-o"/><br /><sub><b>big-o</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=big-o" title="Code">💻</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=big-o" title="Tests">⚠️</a> <a href="#design-big-o" title="Design">🎨</a> <a href="#ideas-big-o" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/aeon-toolkit/aeon/pulls?q=is%3Apr+reviewed-by%3Abig-o" title="Reviewed Pull Requests">👀</a> <a href="#tutorial-big-o" title="Tutorials">✅</a> <a href="#mentoring-big-o" title="Mentoring">🧑‍🏫</a></td>
@@ -271,9 +272,9 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/brettkoonce"><img src="https://avatars2.githubusercontent.com/u/11281814?v=4?s=80" width="80px;" alt="brett koonce"/><br /><sub><b>brett koonce</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=brettkoonce" title="Documentation">📖</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/btrtts"><img src="https://avatars3.githubusercontent.com/u/66252156?v=4?s=80" width="80px;" alt="btrtts"/><br /><sub><b>btrtts</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=btrtts" title="Documentation">📖</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/chizzi25"><img src="https://avatars3.githubusercontent.com/u/67911243?v=4?s=80" width="80px;" alt="chizzi25"/><br /><sub><b>chizzi25</b></sub></a><br /><a href="#blog-chizzi25" title="Blogposts">📝</a></td>
-      <td align="center" valign="top" width="12.5%"><a href="https://github.com/chrisholder"><img src="https://avatars.githubusercontent.com/u/4674372?v=4?s=80" width="80px;" alt="chrisholder"/><br /><sub><b>chrisholder</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=chrisholder" title="Code">💻</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=chrisholder" title="Tests">⚠️</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=chrisholder" title="Documentation">📖</a> <a href="#design-chrisholder" title="Design">🎨</a> <a href="#example-chrisholder" title="Examples">💡</a> <a href="https://github.com/aeon-toolkit/aeon/issues?q=author%3Achrisholder" title="Bug reports">🐛</a></td>
     </tr>
     <tr>
+      <td align="center" valign="top" width="12.5%"><a href="https://github.com/chrisholder"><img src="https://avatars.githubusercontent.com/u/4674372?v=4?s=80" width="80px;" alt="chrisholder"/><br /><sub><b>chrisholder</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=chrisholder" title="Code">💻</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=chrisholder" title="Tests">⚠️</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=chrisholder" title="Documentation">📖</a> <a href="#design-chrisholder" title="Design">🎨</a> <a href="#example-chrisholder" title="Examples">💡</a> <a href="https://github.com/aeon-toolkit/aeon/issues?q=author%3Achrisholder" title="Bug reports">🐛</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/danbartl"><img src="https://avatars.githubusercontent.com/u/19947407?v=4?s=80" width="80px;" alt="danbartl"/><br /><sub><b>danbartl</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/issues?q=author%3Adanbartl" title="Bug reports">🐛</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=danbartl" title="Code">💻</a> <a href="https://github.com/aeon-toolkit/aeon/pulls?q=is%3Apr+reviewed-by%3Adanbartl" title="Reviewed Pull Requests">👀</a> <a href="#talk-danbartl" title="Talks">📢</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=danbartl" title="Tests">⚠️</a> <a href="#tutorial-danbartl" title="Tutorials">✅</a> <a href="#video-danbartl" title="Videos">📹</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/hamzahiqb"><img src="https://avatars3.githubusercontent.com/u/10302415?v=4?s=80" width="80px;" alt="hamzahiqb"/><br /><sub><b>hamzahiqb</b></sub></a><br /><a href="#infra-hamzahiqb" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/hiqbal2"><img src="https://avatars3.githubusercontent.com/u/10302415?v=4?s=80" width="80px;" alt="hiqbal2"/><br /><sub><b>hiqbal2</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=hiqbal2" title="Documentation">📖</a></td>
@@ -281,9 +282,9 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/jschemm"><img src="https://avatars.githubusercontent.com/u/81151346?v=4?s=80" width="80px;" alt="jschemm"/><br /><sub><b>jschemm</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=jschemm" title="Code">💻</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/julu98"><img src="https://avatars.githubusercontent.com/u/133243896?v=4?s=80" width="80px;" alt="julu98"/><br /><sub><b>julu98</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/issues?q=author%3Ajulu98" title="Bug reports">🐛</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/kkoziara"><img src="https://avatars1.githubusercontent.com/u/4346849?v=4?s=80" width="80px;" alt="kkoziara"/><br /><sub><b>kkoziara</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=kkoziara" title="Code">💻</a> <a href="https://github.com/aeon-toolkit/aeon/issues?q=author%3Akkoziara" title="Bug reports">🐛</a></td>
-      <td align="center" valign="top" width="12.5%"><a href="https://github.com/matteogales"><img src="https://avatars0.githubusercontent.com/u/9269326?v=4?s=80" width="80px;" alt="matteogales"/><br /><sub><b>matteogales</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=matteogales" title="Code">💻</a> <a href="#design-matteogales" title="Design">🎨</a> <a href="#ideas-matteogales" title="Ideas, Planning, & Feedback">🤔</a></td>
     </tr>
     <tr>
+      <td align="center" valign="top" width="12.5%"><a href="https://github.com/matteogales"><img src="https://avatars0.githubusercontent.com/u/9269326?v=4?s=80" width="80px;" alt="matteogales"/><br /><sub><b>matteogales</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=matteogales" title="Code">💻</a> <a href="#design-matteogales" title="Design">🎨</a> <a href="#ideas-matteogales" title="Ideas, Planning, & Feedback">🤔</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/oleskiewicz"><img src="https://avatars1.githubusercontent.com/u/5682158?v=4?s=80" width="80px;" alt="oleskiewicz"/><br /><sub><b>oleskiewicz</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=oleskiewicz" title="Code">💻</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=oleskiewicz" title="Documentation">📖</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=oleskiewicz" title="Tests">⚠️</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/pabworks"><img src="https://avatars.githubusercontent.com/u/32725127?v=4?s=80" width="80px;" alt="pabworks"/><br /><sub><b>pabworks</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=pabworks" title="Code">💻</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=pabworks" title="Tests">⚠️</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/xloem"><img src="https://avatars.githubusercontent.com/u/279585?v=4?s=80" width="80px;" alt="patiently pending world peace"/><br /><sub><b>patiently pending world peace</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=xloem" title="Code">💻</a></td>
@@ -291,9 +292,9 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/simone-pignotti"><img src="https://avatars1.githubusercontent.com/u/44410066?v=4?s=80" width="80px;" alt="simone-pignotti"/><br /><sub><b>simone-pignotti</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=simone-pignotti" title="Code">💻</a> <a href="https://github.com/aeon-toolkit/aeon/issues?q=author%3Asimone-pignotti" title="Bug reports">🐛</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/sophijka"><img src="https://avatars2.githubusercontent.com/u/47450591?v=4?s=80" width="80px;" alt="sophijka"/><br /><sub><b>sophijka</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=sophijka" title="Documentation">📖</a> <a href="#maintenance-sophijka" title="Maintenance">🚧</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/sri1419"><img src="https://avatars2.githubusercontent.com/u/65078278?v=4?s=80" width="80px;" alt="sri1419"/><br /><sub><b>sri1419</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=sri1419" title="Code">💻</a></td>
-      <td align="center" valign="top" width="12.5%"><a href="https://github.com/tensorflow-as-tf"><img src="https://avatars.githubusercontent.com/u/51345718?v=4?s=80" width="80px;" alt="tensorflow-as-tf"/><br /><sub><b>tensorflow-as-tf</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=tensorflow-as-tf" title="Code">💻</a></td>
     </tr>
     <tr>
+      <td align="center" valign="top" width="12.5%"><a href="https://github.com/tensorflow-as-tf"><img src="https://avatars.githubusercontent.com/u/51345718?v=4?s=80" width="80px;" alt="tensorflow-as-tf"/><br /><sub><b>tensorflow-as-tf</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=tensorflow-as-tf" title="Code">💻</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/vNtzYy"><img src="https://avatars.githubusercontent.com/u/111287448?v=4?s=80" width="80px;" alt="vNtzYy"/><br /><sub><b>vNtzYy</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/issues?q=author%3AvNtzYy" title="Bug reports">🐛</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/vedazeren"><img src="https://avatars3.githubusercontent.com/u/63582874?v=4?s=80" width="80px;" alt="vedazeren"/><br /><sub><b>vedazeren</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=vedazeren" title="Code">💻</a> <a href="https://github.com/aeon-toolkit/aeon/commits?author=vedazeren" title="Tests">⚠️</a></td>
       <td align="center" valign="top" width="12.5%"><a href="https://github.com/vincent-nich12"><img src="https://avatars3.githubusercontent.com/u/36476633?v=4?s=80" width="80px;" alt="vincent-nich12"/><br /><sub><b>vincent-nich12</b></sub></a><br /><a href="https://github.com/aeon-toolkit/aeon/commits?author=vincent-nich12" title="Code">💻</a></td>
diff --git a/aeon/base/_base_series.py b/aeon/base/_base_series.py
index ba10a63b..79433a7b 100644
--- a/aeon/base/_base_series.py
+++ b/aeon/base/_base_series.py
@@ -195,7 +195,7 @@ class BaseSeriesEstimator(BaseEstimator):
                 X = pd.DataFrame(X)
             else:
                 tag = self.get_tag("X_inner_type")
-                raise ValueError(f"Unknown inner type {inner} derived from {tag}")
+                raise ValueError(f"Unsupported inner type {inner} derived from {tag}")
         if axis > 1 or axis < 0:
             raise ValueError("Axis should be 0 or 1")
         if not self.get_tag("capability:multivariate"):
@@ -235,6 +235,16 @@ class BaseSeriesEstimator(BaseEstimator):
             self.metadata_ = meta
         return self._convert_X(X, axis)
 
+    def _postprocess_series(self, X, axis=None):
+        """Postprocess data X to revert to original shape."""
+        # If a univariate only transformer, return a univariate series
+        if not self.get_tag("capability:multivariate"):
+            return X.squeeze()
+        # If passed an axis, return with that axis
+        if axis is None or axis == self.axis:
+            return X
+        return X.T
+
     @classmethod
     def get_test_params(cls, parameter_set="default"):
         """
diff --git a/aeon/forecasting/base/_base.py b/aeon/forecasting/base/_base.py
index 2942f3e8..af0f0c6a 100644
--- a/aeon/forecasting/base/_base.py
+++ b/aeon/forecasting/base/_base.py
@@ -396,7 +396,8 @@ class BaseForecaster(BaseEstimator):
             # otherwise we call the vectorized version of predict
             y_pred = self._vectorize("predict", X=X_inner, fh=fh)
 
-        # convert to output mtype, identical with last y mtype seen
+        # convert to output type, identical with last y type seen
+
         y_out = convert_to(
             y_pred,
             self._y_mtype_last_seen,
@@ -1411,6 +1412,7 @@ class BaseForecaster(BaseEstimator):
 
         if not requires_vectorization:
             # converts y, skips conversion if already of right type
+
             y_inner = convert_to(
                 y,
                 to_type=y_inner_type,
diff --git a/aeon/forecasting/conformal.py b/aeon/forecasting/conformal.py
index 63fbcd85..63f559eb 100644
--- a/aeon/forecasting/conformal.py
+++ b/aeon/forecasting/conformal.py
@@ -14,8 +14,8 @@ import pandas as pd
 from joblib import Parallel, delayed
 from sklearn.base import clone
 
-from aeon.datatypes import convert, convert_to
 from aeon.forecasting.base import BaseForecaster
+from aeon.utils.conversion import convert_series
 from aeon.utils.index_functions import get_slice
 
 
@@ -249,7 +249,7 @@ class ConformalIntervals(BaseForecaster):
             pred_int.loc[fh_ind] = pred_int_row
 
         y_pred = self.predict(fh=fh, X=X)
-        y_pred = convert(y_pred, from_type=self._y_mtype_last_seen, to_type="pd.Series")
+        y_pred = convert_series(y_pred, output_type="pd.Series")
         y_pred.index = fh_absolute.to_pandas()
 
         for col in cols:
@@ -362,7 +362,7 @@ class ConformalIntervals(BaseForecaster):
             if sample_frac is passed this will have NaN values for 1 - sample_frac
             fraction of the matrix
         """
-        y = convert_to(y, "pd.Series")
+        y = convert_series(y, "pd.Series")
 
         n_initial_window = self._parse_initial_window(y, initial_window=initial_window)
 
diff --git a/aeon/forecasting/model_evaluation/_functions.py b/aeon/forecasting/model_evaluation/_functions.py
index 81b90e96..ddb73904 100644
--- a/aeon/forecasting/model_evaluation/_functions.py
+++ b/aeon/forecasting/model_evaluation/_functions.py
@@ -10,10 +10,15 @@ from typing import List, Optional, Union
 import numpy as np
 import pandas as pd
 
-from aeon.datatypes import convert_to
 from aeon.exceptions import FitFailedWarning
 from aeon.forecasting.base import ForecastingHorizon
-from aeon.utils.validation import is_collection, is_hierarchical, is_single_series
+from aeon.utils.conversion import convert_collection, convert_series
+from aeon.utils.validation import (
+    is_collection,
+    is_hierarchical,
+    is_single_series,
+    validate_input,
+)
 from aeon.utils.validation._dependencies import _check_soft_dependencies
 from aeon.utils.validation.forecasting import check_cv, check_scoring
 
@@ -229,9 +234,9 @@ def evaluate(
         aeon forecaster (concrete BaseForecaster descendant)
     cv : aeon BaseSplitter descendant
         Splitter of how to split the data into test data and train data
-    y : aeon time series container
+    y : aeon time series data structure
         Target (endogeneous) time series used in the evaluation experiment
-    X : aeon time series container, of same mtype as y
+    X : aeon time series data structure, of same type as y
         Exogenous time series used in the evaluation experiment
     strategy : {"refit", "update", "no-update_params"}, optional, default="refit"
         defines the ingestion mode when the forecaster sees new data when window expands
@@ -331,13 +336,20 @@ def evaluate(
     else:
         scoring = check_scoring(scoring)
 
-    if not (is_single_series(y) or is_hierarchical(y) or is_collection(y)):
+    valid, y_metadata = validate_input(y)
+    if not valid:
         raise TypeError(
             f"Expected a series, collection or hierarchy. Got {type(y)} instead."
         )
-
-    y = convert_to(y, to_type=PANDAS_MTYPES)
-
+    if isinstance(y, np.ndarray):
+        if y_metadata["scitype"] == "Series":
+            if y_metadata["is_univariate"]:
+                y = convert_series(y, output_type="pd.Series")
+            else:
+                y = convert_series(y, output_type="pd.DataFrame")
+        elif y_metadata["scitype"] == "Panel":
+            y = convert_collection(y, output_type="pd-multiindex")
+        # If hierarchical, we don't need to convert
     freq = None
     try:
         if y.index.nlevels == 1:
@@ -348,11 +360,22 @@ def evaluate(
         pass
 
     if X is not None:
-        if not (is_single_series(X) or is_hierarchical(X) or is_collection(X)):
+        series = is_single_series(X)
+        hier = is_hierarchical(X)
+        collection = is_collection(X)
+        if not (series or hier or collection):
             raise TypeError(
                 f"Expected a series, collection or hierarchy. Got {type(y)} instead."
             )
-        X = convert_to(X, to_type=PANDAS_MTYPES)
+        _, x_metadata = validate_input(X)
+        if isinstance(X, np.ndarray):
+            if series:
+                if x_metadata["is_univariate"]:
+                    X = convert_series(X, output_type="pd.Series")
+                else:
+                    X = convert_series(X, output_type="pd.DataFrame")
+            elif collection:
+                X = convert_collection(X, output_type="pd-multiindex")
     score_name = (
         f"test_{scoring.__name__}"
         if not isinstance(scoring, List)
diff --git a/aeon/forecasting/model_selection/_split.py b/aeon/forecasting/model_selection/_split.py
index c950a738..a0ed79c4 100644
--- a/aeon/forecasting/model_selection/_split.py
+++ b/aeon/forecasting/model_selection/_split.py
@@ -16,9 +16,9 @@ import pandas as pd
 from sklearn.model_selection import train_test_split as _train_test_split
 
 from aeon.base import BaseObject
-from aeon.datatypes import convert_to
 from aeon.forecasting.base import ForecastingHorizon
 from aeon.forecasting.base._fh import VALID_FORECASTING_HORIZON_TYPES
+from aeon.utils.conversion import convert_collection, convert_series
 from aeon.utils.index_functions import get_index_for_series, get_time_index, get_window
 from aeon.utils.validation import (
     ACCEPTED_WINDOW_LENGTH_TYPES,
@@ -28,11 +28,8 @@ from aeon.utils.validation import (
     array_is_datetime64,
     array_is_int,
     check_window_length,
-    is_collection,
     is_datetime,
-    is_hierarchical,
     is_int,
-    is_single_series,
     is_timedelta,
     is_timedelta_or_date_offset,
     validate_input,
@@ -469,8 +466,6 @@ class BaseSplitter(BaseObject):
         for train, test in self.split(y.index):
             y_train = y.iloc[train]
             y_test = y.iloc[test]
-            y_train = convert_to(y_train, y_orig_mtype)
-            y_test = convert_to(y_test, y_orig_mtype)
             yield y_train, y_test
 
     def _coerce_to_index(self, y: ACCEPTED_Y_TYPES) -> pd.Index:
@@ -499,12 +494,12 @@ class BaseSplitter(BaseObject):
 
         Parameters
         ----------
-        y : pd.Series, pd.DataFrame, or np.ndarray (1D or 2D), optional (default=None)
+        y : pd.Series, pd.DataFrame, or np.ndarray (1D or 2D)
             Time series to check, must conform with one of the aeon type conventions.
 
         Returns
         -------
-        y_inner : time series y coerced to one of the aeon pandas based mtypes:
+        y_inner : time series y as pd.Series or pd.DataFrame
             pd.DataFrame, pd.Series, pd-multiindex, pd_multiindex_hier
             returns pd.Series only if y was pd.Series, otherwise a pandas.DataFrame
         y_mtype : original mtype of y
@@ -513,7 +508,8 @@ class BaseSplitter(BaseObject):
         ------
         TypeError if y is not one of the permissible mtypes
         """
-        if not (is_hierarchical(y) or is_collection(y) or is_single_series(y)):
+        valid, y_metadata = validate_input(y)
+        if not valid:
             raise TypeError(
                 "y must be in an aeon compatible format, "
                 "of scitype Series, Panel or Hierarchical, "
@@ -524,10 +520,16 @@ class BaseSplitter(BaseObject):
                 "run aeon.datatypes.check_raise(y, mtype) to diagnose the error, "
                 "where mtype is the string of the type specification you want for y. "
             )
-        _, y_metadata = validate_input(y)
-
-        y_inner = convert_to(y, to_type=PANDAS_MTYPES)
-
+        y_inner = y
+        if isinstance(y, np.ndarray):
+            if y_metadata["scitype"] == "Series":
+                if y_metadata["is_univariate"]:
+                    y_inner = convert_series(y, output_type="pd.Series")
+                else:
+                    y_inner = convert_series(y, output_type="pd.DataFrame")
+            elif y_metadata["scitype"] == "Panel":
+                y_inner = convert_collection(y, output_type="pd-multiindex")
+            # If hierarchical, it is already in the correct format
         mtype = y_metadata["mtype"]
 
         return y_inner, mtype
diff --git a/aeon/forecasting/naive.py b/aeon/forecasting/naive.py
index 016fa4b3..d0edd218 100644
--- a/aeon/forecasting/naive.py
+++ b/aeon/forecasting/naive.py
@@ -11,10 +11,10 @@ import numpy as np
 import pandas as pd
 from scipy.stats import norm
 
-from aeon.datatypes._convert import convert, convert_to
 from aeon.forecasting.base import ForecastingHorizon
 from aeon.forecasting.base._aeon import _BaseWindowForecaster
 from aeon.forecasting.base._base import DEFAULT_ALPHA, BaseForecaster
+from aeon.utils.conversion import convert_series
 from aeon.utils.index_functions import get_slice
 from aeon.utils.validation import check_window_length
 from aeon.utils.validation.forecasting import check_sp
@@ -362,7 +362,8 @@ class NaiveForecaster(_BaseWindowForecaster):
                 at quantile probability in second-level col index, for each row index.
         """
         y_pred = self.predict(fh)
-        y_pred = convert(y_pred, from_type=self._y_mtype_last_seen, to_type="pd.Series")
+
+        y_pred = convert_series(y_pred, output_type="pd.Series")
 
         pred_var = self.predict_var(fh)
         z_scores = norm.ppf(alpha)
@@ -410,7 +411,7 @@ class NaiveForecaster(_BaseWindowForecaster):
         .. [1] https://otexts.com/fpp3/prediction-intervals.html#benchmark-methods
         """
         y = self._y
-        y = convert_to(y, "pd.Series")
+        y = convert_series(y, "pd.Series")
         T = len(y)
         sp = self.sp
 
@@ -650,7 +651,7 @@ class NaiveVariance(BaseForecaster):
                 at quantile probability in second-level col index, for each row index.
         """
         y_pred = self.predict(fh, X)
-        y_pred = convert(y_pred, from_type=self._y_mtype_last_seen, to_type="pd.Series")
+        y_pred = convert_series(y_pred, output_type="pd.Series")
         pred_var = self.predict_var(fh, X)
         pred_var = pred_var[pred_var.columns[0]]
         pred_var.index = y_pred.index
@@ -753,7 +754,7 @@ class NaiveVariance(BaseForecaster):
             [i,j]-th entry is signed residual of forecasting y.loc[j] from y.loc[:i],
             using a clone of the forecaster passed through the forecaster arg
         """
-        y = convert_to(y, "pd.Series")
+        y = convert_series(y, "pd.Series")
 
         y_index = y.index[initial_window:]
         residuals_matrix = pd.DataFrame(columns=y_index, index=y_index, dtype="float")
diff --git a/aeon/forecasting/squaring_residuals.py b/aeon/forecasting/squaring_residuals.py
index 2adcfdc8..6e3cb492 100644
--- a/aeon/forecasting/squaring_residuals.py
+++ b/aeon/forecasting/squaring_residuals.py
@@ -7,10 +7,10 @@ from warnings import warn
 
 import pandas as pd
 
-from aeon.datatypes._convert import convert_to
 from aeon.forecasting.base import BaseForecaster, ForecastingHorizon
 from aeon.forecasting.model_selection import ExpandingWindowSplitter
 from aeon.forecasting.naive import NaiveForecaster
+from aeon.utils.conversion import convert_series
 
 
 class SquaringResiduals(BaseForecaster):
@@ -154,7 +154,7 @@ class SquaringResiduals(BaseForecaster):
         self._residual_forecaster_ = self.residual_forecaster.clone()
         self._forecaster_ = self.forecaster.clone()
 
-        y = convert_to(y, "pd.Series")
+        y = convert_series(y, "pd.Series")
         cv = ExpandingWindowSplitter(initial_window=self.initial_window, fh=fh_rel)
         self._forecaster_.fit(y=y.iloc[: self.initial_window], X=X)
         y_pred = self._forecaster_.update_predict(y=y, cv=cv, X=X, update_params=True)
diff --git a/aeon/transformations/series/base.py b/aeon/transformations/series/base.py
index 297abb40..878dc2c6 100644
--- a/aeon/transformations/series/base.py
+++ b/aeon/transformations/series/base.py
@@ -101,7 +101,8 @@ class BaseSeriesTransformer(BaseSeriesEstimator, BaseTransformer, metaclass=ABCM
 
         Returns
         -------
-        transformed version of X
+        transformed version of X with the same axis as passed by the user, if axis
+        not None.
         """
         # check whether is fitted
         self.check_is_fitted()
@@ -109,7 +110,8 @@ class BaseSeriesTransformer(BaseSeriesEstimator, BaseTransformer, metaclass=ABCM
         if axis is None:
             axis = self.axis
         X = self._preprocess_series(X, axis=axis)
-        return self._transform(X)
+        Xt = self._transform(X)
+        return self._postprocess_series(Xt, axis=axis)
 
     @final
     def fit_transform(self, X, y=None, axis=None):
@@ -138,14 +140,15 @@ class BaseSeriesTransformer(BaseSeriesEstimator, BaseTransformer, metaclass=ABCM
 
         Returns
         -------
-        transformed version of X
+        transformed version of X with the same axis as passed by the user, if axis
+        not None.
         """
         # input checks and datatype conversion, to avoid doing in both fit and transform
         self.reset()
         X = self._preprocess_series(X, axis=axis)
         Xt = self._fit_transform(X=X, y=y)
         self._is_fitted = True
-        return Xt
+        return self._postprocess_series(Xt, axis=axis)
 
     @final
     def inverse_transform(self, X, y=None, axis=None):
@@ -177,7 +180,8 @@ class BaseSeriesTransformer(BaseSeriesEstimator, BaseTransformer, metaclass=ABCM
         # check whether is fitted
         self.check_is_fitted()
         X = self._preprocess_series(X, axis=axis)
-        return self._inverse_transform(X=X, y=y)
+        Xt = self._inverse_transform(X=X, y=y)
+        return self._postprocess_series(Xt, axis=axis)
 
     @final
     def update(self, X, y=None, update_params=True, axis=None):
diff --git a/aeon/transformations/subset.py b/aeon/transformations/subset.py
index 4a5fdf74..bd4bfe49 100644
--- a/aeon/transformations/subset.py
+++ b/aeon/transformations/subset.py
@@ -15,8 +15,8 @@ class IndexSubset(BaseTransformer):
     If `y` is None, returns `X` without subsetting.
     numpy-based `X` are interpreted as having a RangeIndex starting at n,
     where n is the number of numpy rows seen so far through `fit` and `update`.
-    Non-pandas types are interpreted as having index as after conversion to pandas,
-    via `datatypes.convert_to`, to the `"pd.DataFrame"` aeon type.
+    Non-pandas types are interpreted as having index as after conversion to the
+    `"pd.DataFrame"` aeon type.
 
     Parameters
     ----------
diff --git a/aeon/utils/conversion/__init__.py b/aeon/utils/conversion/__init__.py
index 49842067..cccb33c9 100644
--- a/aeon/utils/conversion/__init__.py
+++ b/aeon/utils/conversion/__init__.py
@@ -4,6 +4,7 @@ __all__ = [
     "resolve_equal_length_inner_type",
     "resolve_unequal_length_inner_type",
     "convert_collection",
+    "convert_series",
 ]
 
 from aeon.utils.conversion._convert_collection import (
@@ -11,3 +12,4 @@ from aeon.utils.conversion._convert_collection import (
     resolve_equal_length_inner_type,
     resolve_unequal_length_inner_type,
 )
+from aeon.utils.conversion._convert_series import convert_series
diff --git a/aeon/utils/conversion/_convert_series.py b/aeon/utils/conversion/_convert_series.py
new file mode 100644
index 00000000..9271244b
--- /dev/null
+++ b/aeon/utils/conversion/_convert_series.py
@@ -0,0 +1,72 @@
+"""Series data converters.
+
+This contains all functions to convert supported collection data types.
+
+String identifier meanings (from aeon.utils.conversion import COLLECTIONS_DATA_TYPES) :
+np.ndarray : 1 or 2D numpy array of time series
+pd.Series:
+pd.DataFrame:
+"""
+
+import numpy as np
+import pandas as pd
+
+
+def convert_series(y, output_type):
+    """Convert series y to the specified output_type.
+
+    y, a single series of type pd.Series, pd.DataFrame or np.ndarray.
+
+    Parameters
+    ----------
+    y : np.ndarray, pd.Series, pd.DataFrame
+        Time series to be converted
+    output_type : string
+        The type to convert y to
+
+    Returns
+    -------
+    converted version of y
+    """
+    if output_type == "np.ndarray":
+        if isinstance(y, (pd.Series, pd.DataFrame)):
+            return y.to_numpy()
+        elif isinstance(y, np.ndarray):
+            return y
+        else:
+            raise ValueError(f"Cannot convert: {type(y)} to np.ndarray")
+    elif output_type == "pd.Series":
+        if isinstance(y, pd.Series):
+            return y
+        elif isinstance(y, pd.DataFrame):
+            if y.shape[1] > 1:
+                raise ValueError(
+                    "DataFrame more than one column, cannot convert to Series"
+                )
+            y = y.iloc[:, 0]
+            return y
+        elif isinstance(y, np.ndarray):
+            if y.ndim == 1:
+                # Convert 1D numpy array to pandas Series
+                return pd.Series(y)
+            else:
+                raise ValueError(
+                    "Cannot convert array with more than one dimension to a pd.Series"
+                )
+    elif output_type == "pd.DataFrame":
+        if isinstance(y, pd.DataFrame):
+            return y
+        elif isinstance(y, pd.Series):
+            return y.to_frame()
+        elif isinstance(y, np.ndarray):
+            return pd.DataFrame(y)
+        else:
+            raise ValueError(
+                f"Unknown output_type: {output_type} must be one of "
+                f"pd.Series, pd.DataFrame or np.ndarray"
+            )
+    else:
+        raise ValueError(
+            f"Unknown output_type: {output_type} must be one of "
+            f"pd.Series, pd.DataFrame or np.ndarray"
+        )
diff --git a/build_tools/run_examples.sh b/build_tools/run_examples.sh
index 9a57fba1..d03c4fc2 100755
--- a/build_tools/run_examples.sh
+++ b/build_tools/run_examples.sh
@@ -5,12 +5,15 @@ set -euxo pipefail
 
 CMD="jupyter nbconvert --to notebook --inplace --execute --ExecutePreprocessor.timeout=600"
 
-excluded=(
-  "examples/datasets/load_data_from_web.ipynb"
-  "examples/benchmarking/reference_results.ipynb"
-  "examples/benchmarking/bakeoff_results.ipynb"
-  "examples/benchmarking/regression.ipynb"
-)
+excluded=()
+if [ "$1" = true ]; then
+  excluded+=(
+    "examples/datasets/load_data_from_web.ipynb"
+    "examples/benchmarking/reference_results.ipynb"
+    "examples/benchmarking/bakeoff_results.ipynb"
+    "examples/benchmarking/regression.ipynb"
+  )
+fi
 
 shopt -s lastpipe
 notebooks=()
diff --git a/docs/api_reference/classification.rst b/docs/api_reference/classification.rst
index 12f2586c..51291c6f 100644
--- a/docs/api_reference/classification.rst
+++ b/docs/api_reference/classification.rst
@@ -20,6 +20,8 @@ Convolution-based
 
     Arsenal
     RocketClassifier
+    HydraClassifier
+    MultiRocketHydraClassifier
 
 Deep learning
 -------------
diff --git a/docs/api_reference/regression.rst b/docs/api_reference/regression.rst
index 0d09a049..fa6a23e8 100644
--- a/docs/api_reference/regression.rst
+++ b/docs/api_reference/regression.rst
@@ -37,6 +37,8 @@ Deep learning
     InceptionTimeRegressor
     IndividualInceptionRegressor
     ResNetRegressor
+    LITETimeRegressor
+    IndividualLITERegressor
 
 Distance-based
 --------------
diff --git a/docs/developer_guide/deprecation.md b/docs/developer_guide/deprecation.md
index 84f5d553..7e5f27e3 100644
--- a/docs/developer_guide/deprecation.md
+++ b/docs/developer_guide/deprecation.md
@@ -18,8 +18,9 @@ Note that the deprecation policy does not necessarily apply to modules we class
 - `benchmarking`
 - `segmentation`
 - `similarity_search`
-- `visualisation`
 - `testing`
+- `transformations/series`
+- `visualisation`
 
 When we introduce a new module, we may classify it as experimental until the API is stable. We will try to not make drastic changes to experimental modules, but we need to retain the freedom to be more agile with the design in these cases.
 
diff --git a/docs/mentoring.md b/docs/mentoring.md
index 99e72879..d9bcaf4d 100644
--- a/docs/mentoring.md
+++ b/docs/mentoring.md
@@ -112,10 +112,8 @@ shapelets.
 
 ##### Expected Outcomes
 
-We expect the mentee engage with the aeon community and produce a performance games
-for the
-We Based on the benchmark of the different implementations, we will evaluate the
-performance gains of the new shapelet transform and the success of this project.
+We expect the mentee to engage with the aeon community and produce a more performant
+implementation for the shapelet transform that gets accepted into the toolkit.
 
 ##### References
 


Test patch:
diff --git a/.github/workflows/periodic_tests.yml b/.github/workflows/periodic_tests.yml
index bf19ded2..2a8922bc 100644
--- a/.github/workflows/periodic_tests.yml
+++ b/.github/workflows/periodic_tests.yml
@@ -73,7 +73,7 @@ jobs:
           command: python -m pip install .[all_extras,binder,dev]
 
       - name: Run example notebooks
-        run: build_tools/run_examples.sh
+        run: build_tools/run_examples.sh false
         shell: bash
 
       - name: Save new cache
diff --git a/aeon/base/tests/test_base_series.py b/aeon/base/tests/test_base_series.py
index 05d62fe2..bbe816f8 100644
--- a/aeon/base/tests/test_base_series.py
+++ b/aeon/base/tests/test_base_series.py
@@ -25,6 +25,11 @@ def test__check_X():
         dummy1._check_X(multi_np)
     with pytest.raises(ValueError, match=r"Multivariate data not supported"):
         dummy1._check_X(multi_pd)
+    missing = np.random.rand(4, 10)
+    missing[3][8] = np.NAN
+    with pytest.raises(ValueError, match=r"Missing values not supported"):
+        dummy1._check_X(missing)
+
     dummy2 = BaseSeriesEstimator()
     all_tags = {
         "capability:multivariate": True,
@@ -58,6 +63,9 @@ def test__check_X():
         dummy2._check_X(uni_np)
     with pytest.raises(ValueError, match=r"Univariate data not supported"):
         dummy2._check_X(uni_pd)
+    wrong_size = np.random.rand(10, 2, 20)
+    with pytest.raises(ValueError, match=r"Should be 1D or 2D"):
+        dummy2._check_X(wrong_size)
 
 
 UNIVARIATE = {
@@ -91,6 +99,14 @@ def test_univariate_convert_X():
             assert type(X2).__name__ == st.split(".")[1]
             X2 = dummy1._convert_X(X, axis=1)
             assert len(X) == len(X2)
+    with pytest.raises(ValueError, match="Axis should be 0 or 1"):
+        dummy1._convert_X(X, axis=2)
+    d = BaseSeriesEstimator.get_test_params()
+    assert d["axis"] == 0
+    all_tags = {"X_inner_type": "numpy3D"}
+    dummy1.set_tags(**all_tags)
+    with pytest.raises(ValueError, match="Unsupported inner"):
+        dummy1._convert_X(X, axis=0)
 
 
 def test_multivariate_convert_X():
@@ -158,3 +174,27 @@ def test_check_y_wrong(y_wrong):
     """Test the _check_y method with incorrect input."""
     with pytest.raises(ValueError, match="Error in input type for y"):
         BaseSeriesEstimator._check_y(None, y_wrong)
+
+
+@pytest.mark.parametrize("returned_type", VALID_TYPES)
+def test__postprocess_series(returned_type):
+    """Test data reformatted correctly."""
+    x = UNIVARIATE[returned_type]
+    dummy1 = BaseSeriesEstimator()
+    tags = {"capability:multivariate": False}
+    dummy1.set_tags(**tags)
+    y = dummy1._postprocess_series(x)
+    y2 = dummy1._postprocess_series(x, axis=0)
+    y3 = dummy1._postprocess_series(x, axis=1)
+    assert y.ndim == 1
+    assert y2.shape == y3.shape
+    tags = {"capability:multivariate": True}
+    dummy1.set_tags(**tags)
+    x = MULTIVARIATE[returned_type]
+    y = dummy1._postprocess_series(x)
+    y2 = dummy1._postprocess_series(x, axis=0)
+    y3 = dummy1._postprocess_series(x, axis=1)
+    assert x.shape == y.shape
+    assert y.shape == y2.shape
+    if returned_type != "pd.Series":
+        assert y.shape[0] == y3.shape[1] and y.shape[1] == y3.shape[0]
diff --git a/aeon/testing/mock_estimators/__init__.py b/aeon/testing/mock_estimators/__init__.py
index 5d51236d..3f51f085 100644
--- a/aeon/testing/mock_estimators/__init__.py
+++ b/aeon/testing/mock_estimators/__init__.py
@@ -12,6 +12,9 @@ __all__ = [
     "SupervisedMockSegmenter",
     "MockHandlesAllInput",
     "MockRegressor",
+    "MockMultivariateSeriesTransformer",
+    "MockSeriesTransformerNoFit",
+    "MockUnivariateSeriesTransformer",
 ]
 
 from aeon.testing.mock_estimators._mock_classifiers import (
@@ -33,3 +36,8 @@ from aeon.testing.mock_estimators._mock_segmenters import (
     MockSegmenter,
     SupervisedMockSegmenter,
 )
+from aeon.testing.mock_estimators._mock_series_transformers import (
+    MockMultivariateSeriesTransformer,
+    MockSeriesTransformerNoFit,
+    MockUnivariateSeriesTransformer,
+)
diff --git a/aeon/testing/mock_estimators/_mock_series_transformers.py b/aeon/testing/mock_estimators/_mock_series_transformers.py
new file mode 100644
index 00000000..c3bea3d3
--- /dev/null
+++ b/aeon/testing/mock_estimators/_mock_series_transformers.py
@@ -0,0 +1,269 @@
+"""Mock series transformers."""
+
+import numpy as np
+
+from aeon.transformations.series import BaseSeriesTransformer
+
+
+class MockUnivariateSeriesTransformer(BaseSeriesTransformer):
+    """
+    MockSeriesTransformer adds a random value and a constant to the input series.
+
+    Parameters
+    ----------
+    constant : int, default=0
+        The constant to be added to each element of the input time series.
+    random_state : int or None, default=None
+        Seed for random number generation.
+    """
+
+    _tags = {
+        "capability:univariate": True,
+        "capability:multivariate": False,
+        "capability:inverse_transform": True,
+    }
+
+    def __init__(self, constant: int = 0, random_state=None) -> None:
+        self.constant = constant
+        self.random_state = random_state
+        super().__init__(axis=1)
+
+    def _fit(self, X: np.ndarray, y=None):
+        """Simulate a fit on X by generating a random value to be added to inputs.
+
+        Parameters
+        ----------
+        X : np.ndarray, shape = (n_channels, n_timepoints)
+            2D time series to be transformed
+        y : ignored argument for interface compatibility
+
+        Returns
+        -------
+        self
+        """
+        self.n_features_ = X.shape[0]
+        rng = np.random.RandomState(seed=self.random_state)
+        self.random_values_ = rng.random(self.n_features_)
+        return self
+
+    def _transform(self, X: np.ndarray, y=None) -> np.ndarray:
+        """Transform X by adding the constant and random value set during fit.
+
+        Parameters
+        ----------
+        X : np.ndarray, shape = (n_channels, n_timepoints)
+            2D time series to be transformed
+        y : ignored argument for interface compatibility
+
+        Returns
+        -------
+        np.ndarray, shape = (n_channels, n_timepoints)
+            2D transformed version of X
+        """
+        X_new = np.zeros_like(X)
+        for i in range(self.n_features_):
+            X_new[i] = X[i] + (self.constant + self.random_values_[i])
+        return X_new
+
+    def _inverse_transform(self, X: np.ndarray, y=None) -> np.ndarray:
+        """Inverse transform X by substracting the constant and random value.
+
+        Parameters
+        ----------
+        X : np.ndarray, shape = (n_channels, n_timepoints)
+            2D time series to be transformed
+        y : ignored argument for interface compatibility
+
+        Returns
+        -------
+        np.ndarray, shape = (n_channels, n_timepoints)
+            2D inverse transformed version of X
+        """
+        X_new = np.zeros_like(X)
+        for i in range(self.n_features_):
+            X_new[i] = X[i] - (self.constant + self.random_values_[i])
+        return X_new
+
+    @classmethod
+    def get_test_params(cls, parameter_set="default"):
+        """
+        Return testing parameter settings for the estimator.
+
+        Parameters
+        ----------
+        parameter_set : str, default="default"
+
+        Returns
+        -------
+        params : dict or list of dict, default = {}
+            Parameters to create testing instances of the class.
+        """
+        return {}
+
+
+class MockMultivariateSeriesTransformer(BaseSeriesTransformer):
+    """
+    MockSeriesTransformer adds a random value and a constant to the input series.
+
+    Parameters
+    ----------
+    constant : int, default=0
+        The constant to be added to each element of the input time series.
+    random_state : int or None, default=None
+        Seed for random number generation.
+    """
+
+    _tags = {
+        "capability:multivariate": True,
+        "capability:inverse_transform": True,
+    }
+
+    def __init__(self, constant: int = 0, random_state=None) -> None:
+        self.constant = constant
+        self.random_state = random_state
+        super().__init__(axis=1)
+
+    def _fit(self, X: np.ndarray, y=None):
+        """Simulate a fit on X by generating a random value to be added to inputs.
+
+        Parameters
+        ----------
+        X : np.ndarray, shape = (n_channels, n_timepoints)
+            2D time series to be transformed
+        y : ignored argument for interface compatibility
+
+        Returns
+        -------
+        self
+        """
+        self.n_features_ = X.shape[0]
+        rng = np.random.RandomState(seed=self.random_state)
+        self.random_values_ = rng.random(self.n_features_)
+        return self
+
+    def _transform(self, X: np.ndarray, y=None) -> np.ndarray:
+        """Transform X by adding the constant and random value set during fit.
+
+        Parameters
+        ----------
+        X : np.ndarray, shape = (n_channels, n_timepoints)
+            2D time series to be transformed
+        y : ignored argument for interface compatibility
+
+        Returns
+        -------
+        np.ndarray, shape = (n_channels, n_timepoints)
+            2D transformed version of X
+        """
+        X_new = np.zeros_like(X)
+        for i in range(self.n_features_):
+            X_new[i] = X[i] + (self.constant + self.random_values_[i])
+        return X_new
+
+    def _inverse_transform(self, X: np.ndarray, y=None) -> np.ndarray:
+        """Inverse transform X by substracting the constant and random value.
+
+        Parameters
+        ----------
+        X : np.ndarray, shape = (n_channels, n_timepoints)
+            2D time series to be transformed
+        y : ignored argument for interface compatibility
+
+        Returns
+        -------
+        np.ndarray, shape = (n_channels, n_timepoints)
+            2D inverse transformed version of X
+        """
+        X_new = np.zeros_like(X)
+        for i in range(self.n_features_):
+            X_new[i] = X[i] - (self.constant + self.random_values_[i])
+        return X_new
+
+    @classmethod
+    def get_test_params(cls, parameter_set="default"):
+        """
+        Return testing parameter settings for the estimator.
+
+        Parameters
+        ----------
+        parameter_set : str, default="default"
+
+        Returns
+        -------
+        params : dict or list of dict, default = {}
+            Parameters to create testing instances of the class.
+        """
+        return {}
+
+
+class MockSeriesTransformerNoFit(BaseSeriesTransformer):
+    """
+    MockSeriesTransformerNoFit adds a value to all elements the input series.
+
+    Parameters
+    ----------
+    constant : int, default=0
+        The constant to be added to each element of the input time series.
+    """
+
+    _tags = {
+        "capability:multivariate": True,
+        "capability:inverse_transform": True,
+        "fit_is_empty": True,
+    }
+
+    def __init__(self, constant: int = 0) -> None:
+        self.constant = constant
+        super().__init__(axis=1)
+
+    def _transform(self, X: np.ndarray, y=None) -> np.ndarray:
+        """Transform X by adding the constant value given in init.
+
+        Parameters
+        ----------
+        X : np.ndarray, shape = (n_channels, n_timepoints)
+            2D time series to be transformed
+        y : ignored argument for interface compatibility
+
+        Returns
+        -------
+        np.ndarray, shape = (n_channels, n_timepoints)
+            2D transformed version of X
+        """
+        X_new = np.zeros_like(X)
+        X_new = X + self.constant
+        return X_new
+
+    def _inverse_transform(self, X: np.ndarray, y=None) -> np.ndarray:
+        """Inverse transform X by substracting the constant.
+
+        Parameters
+        ----------
+        X : np.ndarray, shape = (n_channels, n_timepoints)
+            2D time series to be transformed
+        y : ignored argument for interface compatibility
+
+        Returns
+        -------
+        np.ndarray, shape = (n_channels, n_timepoints)
+            2D inverse transformed version of X
+        """
+        X_new = np.zeros_like(X)
+        X_new = X - self.constant
+        return X_new
+
+    @classmethod
+    def get_test_params(cls, parameter_set="default"):
+        """
+        Return testing parameter settings for the estimator.
+
+        Parameters
+        ----------
+        parameter_set : str, default="default"
+
+        Returns
+        -------
+        params : dict or list of dict, default = {}
+            Parameters to create testing instances of the class.
+        """
+        return {}
diff --git a/aeon/transformations/series/tests/test_base.py b/aeon/transformations/series/tests/test_base.py
index 6db14d43..3320beba 100644
--- a/aeon/transformations/series/tests/test_base.py
+++ b/aeon/transformations/series/tests/test_base.py
@@ -1,1 +1,50 @@
-""""Test the base series transformer."""
+"""Test the base series transformer."""
+
+import numpy as np
+import pytest
+
+from aeon.testing.mock_estimators import (
+    MockMultivariateSeriesTransformer,
+    MockSeriesTransformerNoFit,
+    MockUnivariateSeriesTransformer,
+)
+
+ALL_TRANSFORMERS = [MockMultivariateSeriesTransformer(), MockSeriesTransformerNoFit()]
+MULTIVARIATE_SERIES = [
+    np.array([[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]),
+    np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]),
+    np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]),
+]
+
+
+@pytest.mark.parametrize("transformer", ALL_TRANSFORMERS)
+@pytest.mark.parametrize("series", MULTIVARIATE_SERIES)
+def test_fit_transform_multivariate(transformer, series):
+    """Test fit then transform equivalent to fit_transform with setting axis."""
+    transformer.fit(series)
+    x2 = transformer.transform(series)
+    x3 = transformer.fit_transform(series)
+    np.testing.assert_array_almost_equal(x2, x3)
+    assert series.shape == x2.shape
+
+
+@pytest.mark.parametrize("transformer", ALL_TRANSFORMERS)
+@pytest.mark.parametrize("series", MULTIVARIATE_SERIES)
+def test_axis(transformer, series):
+    """Test axis."""
+    transformer.fit(series, axis=1)
+    x2 = transformer.transform(series, axis=1)
+    assert series.shape == x2.shape
+
+
+def test_fit_transform_univariate():
+    """Test fit transform for univariate."""
+    x1 = np.array([10, 9, 8, 7, 6, 5, 4, 3, 2, 1])
+    transformer = MockUnivariateSeriesTransformer()
+    x2 = transformer.fit_transform(x1)
+    assert x1.shape == x2.shape
+    x3 = np.array([[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]])
+    x4 = transformer.fit_transform(x3)
+    assert isinstance(x4, np.ndarray) and x4.ndim == 1
+    with pytest.raises(ValueError, match="Multivariate data not supported"):
+        transformer.fit_transform(np.random.rand(2, 10))