Skip to content

Commit

Permalink
fix(pandas): generate series and dataframes from class init rather th…
Browse files Browse the repository at this point in the history
…an function

This looks cleaner and is more in line with other pandas extensions
  • Loading branch information
AntoineDao committed Apr 28, 2020
1 parent 1ecc218 commit f557b4f
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 138 deletions.
61 changes: 20 additions & 41 deletions examples/Working With Ladybug Arrays.ipynb

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions ladybug_pandas/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""ladybug-pandas library."""

from .dataframe import dataframe_from_collections, dataframe_from_epw
from .series import series_from_collection
from .dataframe import DataFrame
from .series import Series

from .accessors.ladybug import LadybugSeriesAccessor, LadybugDataFrameAccessor
from .accessors.psychrometrics import PsychrometricsAccessor
163 changes: 85 additions & 78 deletions ladybug_pandas/dataframe.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,110 +6,117 @@
from ladybug.epw import EPW
from .extension_types.arraytype import LadybugArrayType

def dataframe_from_collections(
data_collections: List[Union[HourlyDiscontinuousCollection, HourlyContinuousCollection, DailyCollection, MonthlyCollection, MonthlyPerHourCollection]],
name_key: str = None,
) -> pd.DataFrame:
"""Generate a Dataframe from a list of ladybug data collections

Example:
.. code-block:: python
import ladybug_pandas as lbp
from ladybug.wea import Wea
from ladybug.location import Location
class DataFrame:

location = Location(
city='Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch',
state='Wales',
country='United Kingdom',
latitude=53.224622,
longitude=-4.197995,
time_zone=0
)
def __new__(
cls,
data_collections: List[Union[HourlyDiscontinuousCollection, HourlyContinuousCollection, DailyCollection, MonthlyCollection, MonthlyPerHourCollection]],
name_key: str = None,
) -> pd.DataFrame:
"""Generate a Dataframe from a list of ladybug data collections
wea = Wea.from_ashrae_clear_sky(location=location)
Example:
.. code-block:: python
df = lbp.dataframe_from_collections([
wea.direct_normal_irradiance,
wea.diffuse_horizontal_irradiance,
wea.global_horizontal_irradiance,
wea.direct_horizontal_irradiance,
])
import ladybug_pandas as lbp
from ladybug.wea import Wea
from ladybug.location import Location
Arguments:
data_collections {List[Union[HourlyDiscontinuousCollection, HourlyContinuousCollection, DailyCollection, MonthlyCollection, MonthlyPerHourCollection]]} -- A list of datacollections. Must all be of the same type
location = Location(
city='Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch',
state='Wales',
country='United Kingdom',
latitude=53.224622,
longitude=-4.197995,
time_zone=0
)
Keyword Arguments:
name_key {str} -- The name of the metadata key to use as a column name. Will default to datatype name if not specified (default: {None})
wea = Wea.from_ashrae_clear_sky(location=location)
Returns:
pd.DataFrame -- A pandas dataframe. Each column will have a type of LadybugArrayType
"""

data_collection_type = None
df = lbp.DataFrame([
wea.direct_normal_irradiance,
wea.diffuse_horizontal_irradiance,
wea.global_horizontal_irradiance,
wea.direct_horizontal_irradiance,
])
df_list = []
Arguments:
data_collections {List[Union[HourlyDiscontinuousCollection, HourlyContinuousCollection, DailyCollection, MonthlyCollection, MonthlyPerHourCollection]]} -- A list of datacollections. Must all be of the same type
for collection in data_collections:
# Check they are data collections
assert isinstance(collection, BaseCollection), \
f'All items of data_collections must be a type of ladybug data collection, not: {type(collection)}'
Keyword Arguments:
name_key {str} -- The name of the metadata key to use as a column name. Will default to datatype name if not specified (default: {None})
# Assert same type of data collection
if data_collection_type is None:
data_collection_type = type(collection)
else:
assert isinstance(collection, data_collection_type), \
f'All items of data_collections must be of the same type of data collection. Found {data_collection_type} and {type(collection)}'
Returns:
pd.DataFrame -- A pandas dataframe. Each column will have a type of LadybugArrayType
"""

data_collection_type = None

df_list = []

# Create columns from collections
array = LadybugArrayType._from_data_collection(collection)
for collection in data_collections:
# Check they are data collections
assert isinstance(collection, BaseCollection), \
f'All items of data_collections must be a type of ladybug data collection, not: {type(collection)}'

if name_key is not None:
col_name = collection.header.metadata[name_key]
else:
col_name = collection.header.data_type.name
# Assert same type of data collection
if data_collection_type is None:
data_collection_type = type(collection)
else:
assert isinstance(collection, data_collection_type), \
f'All items of data_collections must be of the same type of data collection. Found {data_collection_type} and {type(collection)}'

data = {}

data[col_name] = array
# Create columns from collections
array = LadybugArrayType._from_data_collection(collection)

df_list.append(pd.DataFrame(
data=data,
index=collection.datetimes
))
if name_key is not None:
col_name = collection.header.metadata[name_key]
else:
col_name = collection.header.data_type.name

df = pd.concat(df_list, axis=1)
data = {}

return df
data[col_name] = array

df_list.append(pd.DataFrame(
data=data,
index=collection.datetimes
))

def dataframe_from_epw(
epw: EPW
) -> pd.DataFrame:
"""Generate a Dataframe from an EPW object
df = pd.concat(df_list, axis=1)

Example:
.. code-block:: python
return df

import ladybug_pandas as lbp
from ladybug.epw import EPW

epw_path = 'tests/assets/epw/tokyo.epw'
@classmethod
def from_epw(
cls,
epw: EPW
) -> pd.DataFrame:
"""Generate a Dataframe from an EPW object
epw = EPW(epw_path)
Example:
.. code-block:: python
df = lbp.dataframe_from_epw(epw)
import ladybug_pandas as lbp
from ladybug.epw import EPW
Arguments:
epw {EPW} -- A ladybug EPW object
epw_path = 'tests/assets/epw/tokyo.epw'
Returns:
pd.DataFrame -- A pandas dataframe. Each column will have a type of LadybugArrayType
"""
df = dataframe_from_collections(epw._data[6:])
epw = EPW(epw_path)
df = df.replace(999999999.0, np.nan)
df = lbp.DataFrame.from_epw(epw)
return df
Arguments:
epw {EPW} -- A ladybug EPW object
Returns:
pd.DataFrame -- A pandas dataframe. Each column will have a type of LadybugArrayType
"""
df = cls(epw._data[6:])

df = df.replace(999999999.0, np.nan)

return df
47 changes: 35 additions & 12 deletions ladybug_pandas/series.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,42 @@
import pandas as pd
from .extension_types.arraytype import LadybugArrayType

def series_from_collection(data_collection) -> pd.Series:
"""Generate a pandas Series from a Ladybug Data Collection
class Series:

Arguments:
data_collection {ladybug._datacollectionbase.BaseCollection} -- An instance of a ladybug data collection
def __new__(cls, data_collection) -> pd.Series:
"""Generate a pandas Series from a Ladybug Data Collection
Returns:
pd.Series -- A pandas Series of type Ladybug Array
"""
Example:
.. code-block:: python
array = LadybugArrayType._from_data_collection(data_collection)
import ladybug_pandas as lbp
from ladybug.wea import Wea
from ladybug.location import Location
location = Location(
city='Taumatawhakatangi­hangakoauauotamatea­turipukakapikimaunga­horonukupokaiwhen­uakitanatahu',

This comment has been minimized.

Copy link
@AntoineDao

AntoineDao Apr 28, 2020

Author Member

This one is for you @sariths

This comment has been minimized.

Copy link
@sariths

sariths Apr 28, 2020

@AntoineDao Awesome!! I was wondering if the name would overrun the string-size allowance, I guess it doesn't.

state='Wales',
country='United Kingdom',
latitude=-40.3500,
longitude=176.5500,
time_zone=12
)
wea = Wea.from_ashrae_clear_sky(location=location)
series = lbp.Series(wea.direct_normal_irradiance)
Arguments:
data_collection {ladybug._datacollectionbase.BaseCollection} -- An instance of a ladybug data collection
Returns:
pd.Series -- A pandas Series of type Ladybug Array
"""

array = LadybugArrayType._from_data_collection(data_collection)

return pd.Series(
data=array,
index=data_collection.datetimes
)

return pd.Series(
data=array,
index=data_collection.datetimes
)
10 changes: 5 additions & 5 deletions tests/op_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from ladybug_pandas.extension_types.dtype import LadybugDType
from ladybug_pandas.extension_types.arraytype import LadybugArrayType

from ladybug_pandas import dataframe_from_collections, dataframe_from_epw, series_from_collection
from ladybug_pandas import DataFrame, Series

@pytest.fixture(scope='session')
def epw():
Expand All @@ -23,11 +23,11 @@ def epw():

@pytest.fixture()
def temp_series(epw):
return series_from_collection(epw.dry_bulb_temperature)
return Series(epw.dry_bulb_temperature)

@pytest.fixture()
def dnr_series(epw):
return series_from_collection(epw.direct_normal_radiation)
return Series(epw.direct_normal_radiation)


def test_addition(temp_series, dnr_series):
Expand All @@ -47,13 +47,13 @@ def test_conversion(temp_series):

def test_from_collections(epw):

df = dataframe_from_collections([epw.dry_bulb_temperature, epw.direct_normal_radiation])
df = DataFrame([epw.dry_bulb_temperature, epw.direct_normal_radiation])

# should not raise

def test_from_epw(epw):

df = dataframe_from_epw(epw)
df = DataFrame.from_epw(epw)

# should not raise

Expand Down

0 comments on commit f557b4f

Please sign in to comment.