Skip to content

Commit

Permalink
Merge pull request #188 from WenjieDu/dev
Browse files Browse the repository at this point in the history
Merge dev into main
  • Loading branch information
WenjieDu authored Sep 18, 2023
2 parents 4cfaa1c + a329f79 commit a22a01a
Show file tree
Hide file tree
Showing 16 changed files with 221 additions and 32 deletions.
2 changes: 2 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<!-- 🚨Please create your PR to merge code from your branch to `dev` branch here, rather than `main`. -->

# What does this PR do?

<!--
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/greetings.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Autoreply to Issues Opened for PyPOTS
name: Auto reply to new issues and PR

on:
issues:
Expand Down Expand Up @@ -28,7 +28,6 @@ jobs:
Best,
Wenjie
pr-message: |
Hi there 👋,
Expand Down
20 changes: 20 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# ignore special files or folds
*~
.idea
.DS_Store

# ignore all building results
dist
build
docs/_build
*.egg-info

# ignore all testing/running results
.run
.coverage
.pytest_cache
*__pycache__*
*testing_results*

# ignore specific kinds of files like all PDFs
*.pdf
2 changes: 1 addition & 1 deletion .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ build:
- pip install torch==1.13.1 -f https://download.pytorch.org/whl/cpu
- pip install torch-geometric torch-scatter torch-sparse -f "https://data.pyg.org/whl/torch-1.13.1+cpu.html"
- pip install pypots
- pip install sphinx==6.2.1 docutils==0.19 sphinxcontrib-bibtex==2.1.4 sphinxcontrib-gtagjs sphinx-autodoc-typehints furo
- pip install sphinx==6.2.1 docutils==0.19 sphinxcontrib-bibtex==2.1.4 sphinxcontrib-gtagjs sphinx-autodoc-typehints furo==2023.07.26

post_install:
- pip install docutils==0.20
Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
prune tests
prune pypots/*/template
prune pypots/*/README.md
21 changes: 12 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<a href="https://github.com/WenjieDu/PyPOTS">
<img src="https://raw.githubusercontent.com/PyPOTS/pypots.github.io/main/static/figs/pypots_logos/PyPOTS_logo_FFBG.svg?sanitize=true" width="200" align="right">
<img src="https://pypots.com/figs/pypots_logos/PyPOTS_logo_FFBG.svg?sanitize=true" width="200" align="right">
</a>

## <p align="center">Welcome to PyPOTS</p>
Expand All @@ -9,12 +9,14 @@
<a href="https://docs.pypots.com/en/latest/install.html#reasons-of-version-limitations-on-dependencies">
<img alt="Python version" src="https://img.shields.io/badge/Python-v3.7--3.10-E97040?logo=python&logoColor=white">
</a>
<img alt="powered by Pytorch" src="https://img.shields.io/badge/PyTorch-❤️-F8C6B5?logo=pytorch&logoColor=white">
<a href="https://pypi.org/project/PyPOTS">
<img alt="the latest release version" src="https://img.shields.io/github/v/release/wenjiedu/pypots?color=EE781F&include_prereleases&label=Release">
<a href="https://github.com/WenjieDu/PyPOTS">
<img alt="powered by Pytorch" src="https://img.shields.io/badge/PyTorch-❤️-F8C6B5?logo=pytorch&logoColor=white">
</a>
<a href="https://github.com/WenjieDu/PyPOTS/releases">
<img alt="the latest release version" src="https://img.shields.io/github/v/release/wenjiedu/pypots?color=EE781F&include_prereleases&label=Release&logo=github&logoColor=white">
</a>
<a href="https://github.com/WenjieDu/PyPOTS/blob/main/LICENSE">
<img alt="GPL-v3 license" src="https://img.shields.io/badge/License-GPL--v3-E9BB41">
<img alt="GPL-v3 license" src="https://img.shields.io/badge/License-GPL--v3-E9BB41?logo=opensourceinitiative&logoColor=white">
</a>
<a href="https://github.com/WenjieDu/PyPOTS/blob/main/README.md#-community">
<img alt="Community" src="https://img.shields.io/badge/join_us-community!-C8A062">
Expand All @@ -41,10 +43,10 @@
<img alt="arXiv DOI" src="https://img.shields.io/badge/DOI-10.48550/arXiv.2305.18811-F8F7F0">
</a>
<a href="https://anaconda.org/conda-forge/pypots">
<img alt="Conda downloads" src="https://img.shields.io/conda/dn/conda-forge/pypots?label=Conda%20Downloads&color=AED0ED&logo=anaconda&logoColor=white">
<img alt="Conda downloads" src="https://img.shields.io/endpoint?url=https://pypots.com/figs/downloads_badges/conda_pypots_downloads.json">
</a>
<a href="https://pepy.tech/project/pypots">
<img alt="PyPI downloads" src="https://static.pepy.tech/personalized-badge/pypots?period=total&units=international_system&left_color=grey&right_color=blue&left_text=PyPI%20Downloads">
<img alt="PyPI downloads" src="https://img.shields.io/endpoint?url=https://pypots.com/figs/downloads_badges/pypi_pypots_downloads.json">
</a>

</p>
Expand All @@ -66,7 +68,7 @@ have unified APIs together with detailed documentation and interactive examples
if it helps with your research. This really means a lot to our open-source research. Thank you!

<a href="https://github.com/WenjieDu/TSDB">
<img src="https://raw.githubusercontent.com/PyPOTS/pypots.github.io/main/static/figs/pypots_logos/TSDB_logo_FFBG.svg?sanitize=true" align="left" width="160" alt="TSDB logo"/>
<img src="https://pypots.com/figs/pypots_logos/TSDB_logo_FFBG.svg?sanitize=true" align="left" width="160" alt="TSDB logo"/>
</a>

To make various open-source time-series datasets readily available to our users,
Expand Down Expand Up @@ -108,7 +110,7 @@ Alternatively, you can install from the latest source code with the latest featu

## ❖ Usage
<a href="https://github.com/WenjieDu/BrewPOTS">
<img src="https://raw.githubusercontent.com/PyPOTS/pypots.github.io/main/static/figs/pypots_logos/BrewPOTS_logo_FFBG.svg?sanitize=true" align="left" width="160" alt="BrewPOTS logo"/>
<img src="https://pypots.com/figs/pypots_logos/BrewPOTS_logo_FFBG.svg?sanitize=true" align="left" width="160" alt="BrewPOTS logo"/>
</a>

PyPOTS tutorials have been released. Considering the future workload, I separate the tutorials into a single repo,
Expand Down Expand Up @@ -269,3 +271,4 @@ PyPOTS community is open, transparent, and surely friendly. Let's work together
<img alt="PyPOTS visits" align="left" src="https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2FPyPOTS%2FPyPOTS&count_bg=%23009A0A&title_bg=%23555555&icon=&icon_color=%23E7E7E7&title=Visits%20since%20May%202022&edge_flat=false">
</a>
</details>
<br>
2 changes: 1 addition & 1 deletion docs/examples.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Quick-start Examples
====================

.. image:: https://raw.githubusercontent.com/PyPOTS/pypots.github.io/main/static/figs/pypots_logos/BrewPOTS_logo_FFBG.svg?sanitize=true
.. image:: https://pypots.com/figs/pypots_logos/BrewPOTS_logo_FFBG.svg?sanitize=true
:width: 160
:alt: BrewPOTS logo
:align: right
Expand Down
7 changes: 4 additions & 3 deletions docs/faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ and

**NOTE**: The maintainer role is not permanent. The role is called "maintainer" because it actively maintains the project.
You can take a leave of absence from the role with notice at any time.
But if you're inactive for a long time (more than three months. With reasons, a longer period is allowed for sure), your role will be deactivated.
But if you're inactive for a long time (more than three months. With reasons, a longer period is allowed for sure), your role may be deactivated.

Becoming a Lead
"""""""""""""""
Expand All @@ -52,7 +52,8 @@ The lead is a permanent role unless your research is no longer related to the fi
you no longer want to get involved with affairs at PyPOTS.

If you believe you want to do this, you can drop an email with anything you want to tell and your CV attachment to
`[email protected] <mailto:[email protected]>`_. We will schedule a meeting for you and all other leads at PyPOTS for further discussion.
`[email protected] <mailto:[email protected]>`_. We will schedule a meeting for you and all other members at PyPOTS for further discussion.
This is absolutely not a so-called interview, please don't take it formal and we just would like to listen to your thoughts about the field of POTS ;-)


Our Development Principles
Expand All @@ -64,7 +65,7 @@ Our Development Principles
We develop PyPOTS and we should try the best to use it in any scenarios related to POTS data.
Only in this way, we can figure out how it tastes like, if it is a good toolset for users, and what other features and models should be included into PyPOTS;
3. `No silver bullet <https://en.wikipedia.org/wiki/No_Silver_Bullet>`_ and `No free launch <https://en.wikipedia.org/wiki/No_free_lunch_theorem>`_.
There is no one solution to all problems in the Universe. In PyPOTS, we keep things modular, so one can easily try and replace parts of the pipeline
There is no one solution to all problems in the universe. In PyPOTS, we keep things modular, so one can easily try and replace parts of the pipeline
in search for the optimal combination for the particular task;
4. Keep things easy to use and familiar. We try to keep PyPOTS intuitive without compromising flexibility and without forcing users to learn a completely new technology.
We do this by keeping the toolkit close to APIs in scikit-learn and pytorch that people know and love;
20 changes: 11 additions & 9 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,27 @@
Welcome to PyPOTS docs!
===============================
.. image:: https://raw.githubusercontent.com/PyPOTS/pypots.github.io/main/static/figs/pypots_logos/PyPOTS_logo_FFBG.svg?sanitize=true
.. image:: https://pypots.com/figs/pypots_logos/PyPOTS_logo_FFBG.svg?sanitize=true
:height: 168
:align: right
:target: https://github.com/WenjieDu/PyPOTS
:alt: PyPOTS logo

.. centered:: A Python Toolbox for Data Mining on Partially-Observed Time Series
**A Python Toolbox for Data Mining on Partially-Observed Time Series**

.. image:: https://img.shields.io/badge/Python-v3.7--3.10-E97040?logo=python&logoColor=white
:alt: Python version
:target: https://docs.pypots.com/en/latest/install.html#reasons-of-version-limitations-on-dependencies

.. image:: https://img.shields.io/badge/PyTorch-❤️-F8C6B5?logo=pytorch&logoColor=white
:alt: powered by Pytorch
:target: https://github.com/WenjieDu/PyPOTS

.. image:: https://img.shields.io/github/v/release/wenjiedu/pypots?color=EE781F&include_prereleases&label=Release
.. image:: https://img.shields.io/github/v/release/wenjiedu/pypots?color=EE781F&include_prereleases&label=Release&logo=github&logoColor=white
:alt: the latest release version
:target: https://pypi.org/project/pypots
:target: https://github.com/WenjieDu/PyPOTS/releases

.. image:: https://img.shields.io/badge/License-GPL--v3-E9BB41
.. image:: https://img.shields.io/badge/License-GPL--v3-E9BB41?logo=opensourceinitiative&logoColor=white
:alt: GPL-v3 license
:target: https://github.com/WenjieDu/PyPOTS/blob/main/LICENSE

Expand Down Expand Up @@ -58,11 +60,11 @@ Welcome to PyPOTS docs!
:alt: arXiv DOI
:target: https://arxiv.org/abs/2305.18811

.. image:: https://img.shields.io/conda/dn/conda-forge/pypots?label=Conda%20Downloads&color=AED0ED&logo=anaconda&logoColor=white
.. image:: https://img.shields.io/endpoint?url=https://pypots.com/figs/downloads_badges/conda_pypots_downloads.json
:alt: Conda downloads
:target: https://anaconda.org/conda-forge/pypots

.. image:: https://static.pepy.tech/personalized-badge/pypots?period=total&units=international_system&left_color=grey&right_color=blue&left_text=PyPI%20Downloads
.. image:: https://img.shields.io/endpoint?url=https://pypots.com/figs/downloads_badges/pypi_pypots_downloads.json
:alt: PyPI downloads
:target: https://pepy.tech/project/pypots

Expand All @@ -80,7 +82,7 @@ Welcome to PyPOTS docs!
**Please** properly `cite PyPOTS <https://docs.pypots.com/en/latest/milestones.html#citing-pypots>`_ in your publications
if it helps with your research. This really means a lot to our open-source research. Thank you!

.. image:: https://raw.githubusercontent.com/PyPOTS/pypots.github.io/main/static/figs/pypots_logos/TSDB_logo_FFBG.svg?sanitize=true
.. image:: https://pypots.com/figs/pypots_logos/TSDB_logo_FFBG.svg?sanitize=true
:width: 170
:alt: TSDB
:align: left
Expand Down Expand Up @@ -108,7 +110,7 @@ Refer to the page `Installation <install.html>`_ to see different ways of instal

❖ Usage
^^^^^^^^
.. image:: https://raw.githubusercontent.com/PyPOTS/pypots.github.io/main/static/figs/pypots_logos/BrewPOTS_logo_FFBG.svg?sanitize=true
.. image:: https://pypots.com/figs/pypots_logos/BrewPOTS_logo_FFBG.svg?sanitize=true
:width: 160
:alt: BrewPOTS logo
:align: left
Expand Down
4 changes: 2 additions & 2 deletions docs/pypots.utils.rst
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
pypots.utils package
====================

pypots.utils.files module
pypots.utils.file module
-------------------------

.. automodule:: pypots.utils.files
.. automodule:: pypots.utils.file
:members:
:undoc-members:
:show-inheritance:
Expand Down
3 changes: 3 additions & 0 deletions pypots/data/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
pickle_load,
pickle_dump,
)
from .saving import save_dict_into_h5

__all__ = [
# datasets
Expand All @@ -39,4 +40,6 @@
"mcar",
"pickle_load",
"pickle_dump",
# saving
"save_dict_into_h5",
]
43 changes: 43 additions & 0 deletions pypots/data/saving.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""
Data saving utilities.
"""

# Created by Wenjie Du <[email protected]>
# License: GLP-v3


import os

import h5py

from pypots.utils.file import create_dir_if_not_exist
from pypots.utils.logging import logger


def save_dict_into_h5(data_dict: dict, saving_dir: str) -> None:
"""Save the given data (in a dictionary) into the given h5 file.
Parameters
----------
data_dict : dict,
The data to be saved, should be a Python dictionary.
saving_dir : str,
The h5 file to save the data.
"""

def save_set(handle, name, data):
if isinstance(data, dict):
single_set_handle = handle.create_group(name)
for key, value in data.items():
save_set(single_set_handle, key, value)
else:
handle.create_dataset(name, data=data)

create_dir_if_not_exist(saving_dir)
saving_path = os.path.join(saving_dir, "datasets.h5")
with h5py.File(saving_path, "w") as hf:
for k, v in data_dict.items():
save_set(hf, k, v)
logger.info(f"Successfully saved the given data into {saving_path}.")
43 changes: 43 additions & 0 deletions pypots/data/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,46 @@ def cal_delta_for_single_sample(mask: np.ndarray) -> np.ndarray:
delta_collector.append(delta)
delta = np.asarray(delta_collector)
return delta


def sliding_window(time_series, n_steps, sliding_len=None):
"""Generate time series samples with sliding window method, truncating windows from time-series data
with a given sequence length.
Given a time series of shape [seq_len, n_features] (seq_len is the total sequence length of the time series), this
sliding_window function will generate time-series samples from this given time series with sliding window method.
The number of generated samples is seq_len//sliding_len. And the final returned numpy ndarray has a shape
[seq_len//sliding_len, n_steps, n_features].
Parameters
----------
time_series : np.ndarray,
time series data, len(shape)=2, [total_length, feature_num]
n_steps : int,
The number of time steps in the generated data samples.
sliding_len : int, default = None,
The size of the sliding window. It will be set as the same with n_steps if None.
Returns
-------
samples : np.ndarray,
The generated time-series data samples of shape [seq_len//sliding_len, n_steps, n_features].
"""
sliding_len = n_steps if sliding_len is None else sliding_len
total_len = time_series.shape[0]
start_indices = np.asarray(range(total_len // sliding_len)) * sliding_len

# remove the last one if left length is not enough
if total_len - start_indices[-1] * sliding_len < n_steps:
start_indices = start_indices[:-1]

sample_collector = []
for idx in start_indices:
sample_collector.append(time_series[idx : idx + n_steps])

samples = np.asarray(sample_collector).astype("float32")

return samples
2 changes: 1 addition & 1 deletion pypots/imputation/saits/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def forward(
if (training and self.diagonal_attention_mask) or (
(not training) and diagonal_attention_mask
):
diagonal_attention_mask = torch.eye(self.n_steps).to(X.device)
diagonal_attention_mask = (1 - torch.eye(self.n_steps)).to(X.device)
# then broadcast on the batch axis
diagonal_attention_mask = diagonal_attention_mask.unsqueeze(0)
else:
Expand Down
8 changes: 4 additions & 4 deletions pypots/modules/self_attention.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def forward(

# apply masking on the attention map, this is optional
if attn_mask is not None:
attn = attn.masked_fill(attn_mask == 1, -1e9)
attn = attn.masked_fill(attn_mask == 0, -1e9)

# compute attention score [0, 1], then apply dropout
attn = self.dropout(F.softmax(attn, dim=-1))
Expand Down Expand Up @@ -207,10 +207,10 @@ def forward(
dec_enc_attn_mask: Optional[torch.Tensor] = None,
) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
dec_output, dec_slf_attn = self.slf_attn(
dec_input, dec_input, dec_input, mask=slf_attn_mask
dec_input, dec_input, dec_input, attn_mask=slf_attn_mask
)
dec_output, dec_enc_attn = self.enc_attn(
dec_output, enc_output, enc_output, mask=dec_enc_attn_mask
dec_output, enc_output, enc_output, attn_mask=dec_enc_attn_mask
)
dec_output = self.pos_ffn(dec_output)
return dec_output, dec_slf_attn, dec_enc_attn
Expand Down Expand Up @@ -288,7 +288,7 @@ def __init__(
self.embedding = nn.Linear(n_features, d_model)
self.dropout = nn.Dropout(dropout)
self.position_enc = PositionalEncoding(d_model, n_position=n_steps)
self.dec_layer_stack = nn.ModuleList(
self.layer_stack = nn.ModuleList(
[
DecoderLayer(
d_model,
Expand Down
Loading

0 comments on commit a22a01a

Please sign in to comment.