Triangle#
- class chainladder.Triangle(data: DataFrame | DataFrameXchg | dict | None = None, origin: str | list | None = None, development: str | list | None = None, columns: str | list | None = None, index: str | list | None = None, origin_format: str | None = None, development_format: str | None = None, cumulative: bool | None = None, array_backend: str = None, pattern=False, trailing: bool = True, *args, **kwargs)[source]#
The core data structure of the chainladder package
- Parameters:
- data: DataFrame or DataFrameXchg, or dict
A single dataframe that contains columns representing all other arguments to the Triangle constructor. One may supply a DataFrame-like object (referred to as DataFrameXchg) supporting the __dataframe__ protocol, which will then be converted to a pandas DataFrame. If supplying a dict, it must be structured such that a pandas DataFrame created from it will be accepted by the constructor. If omitted (or if all arguments are omitted), an empty Triangle is returned.
- origin: str
Name of the column in
datarepresenting the accident, reporting, or more generally the origin period. Maps to the Origin dimension.- development: str
Name of the column in
datarepresenting the development or valuation period. Maps to the Development dimension. If omitted, the Triangle is treated as having a single development period (e.g. a latest-diagonal-only view).- columns: str or list
Name(s) of the column(s) in
dataholding the numeric values that will map to the columns dimension. If omitted, a single'Total'key is generated.- index: str or list
Name(s) of the column(s) in
datathat will map to the index dimension. If omitted, a single'Total'key is generated.- origin_format: str
A string representation of the date format of the origin column (e.g.
'%Y-%m-%d'). If omitted, the date format is inferred by pandas.- development_format: str
A string representation of the date format of the development column. If omitted, the date format is inferred by pandas.
- cumulative: bool
Whether the triangle is cumulative or incremental. This attribute is required to use the
grainanddev_to_valmethods and will be automatically set when invokingcum_to_incrorincr_to_cummethods.- trailing: bool, default True
Controls how the period-end month is inferred from origin and development dates. When False, December is treated as the period end (i.e., calendar fiscal periods). When True, the period end is inferred from the data itself. This is useful when origin dates do not align with calendar period boundaries.
- array_backend: str, optional (default = None)
Backend used to store the underlying values array. One of
'numpy','sparse', or'cupy'(if installed). IfNone, falls back tocl.options.ARRAY_BACKEND.
- Attributes:
- index: Series
Represents all available levels of the index dimension.
- columns: Series
Represents all available levels of the value dimension.
- origin: DatetimeIndex
Represents all available levels of the origin dimension.
- development: Series
Represents all available levels of the development dimension.
- key_labels: list
Represents the
indexaxis labels- virtual_columns: Series
Represents the subset of columns of the triangle that are virtual.
- valuation: DatetimeIndex
Represents all valuation dates of each cell in the Triangle.
- origin_grain: str
The grain of the origin vector (‘Y’, ‘S’, ‘Q’, ‘M’)
- development_grain: str
The grain of the development vector (‘Y’, ‘S’, ‘Q’, ‘M’)
- shape: tuple
The 4D shape of the triangle instance with axes corresponding to (index, columns, origin, development)
- link_ratio, age_to_age
Displays age-to-age ratios for the triangle.
- valuation_datedate
The latest valuation date of the data
- loc: Triangle
pandas-style
locaccessor- iloc: Triangle
pandas-style
ilocaccessor- latest_diagonal: Triangle
The latest diagonal of the triangle
- is_cumulative: bool
Whether the triangle is cumulative or not
- is_ultimate: bool
Whether the triangle has an ultimate valuation
- is_full: bool
Whether lower half of Triangle has been filled in
- is_val_tri:
Whether the triangle development period is expressed as valuation periods.
- values: array
4D numpy array underlying the Triangle instance
- T: Triangle
Transpose index and columns of object. Only available when Triangle is convertible to DataFrame.
Examples
Constructing a Triangle from a Pandas DataFrame.
import pandas as pd df = pd.DataFrame( data={ 'origin': [1981, 1981, 1981, 1981, 1982, 1982, 1982, 1983, 1983, 1984], 'development': [1981, 1982, 1983, 1984, 1982, 1983, 1984, 1983, 1984, 1984], 'reported': [5012, 8269, 10907, 11805, 106, 4285, 5396, 3410, 8992, 5655], } ) tr = cl.Triangle( data=df, origin='origin', development='development', columns=['reported'], cumulative=True, ) print(tr)
12 24 36 48 1981 5012.0 8269.0 10907.0 11805.0 1982 106.0 4285.0 5396.0 NaN 1983 3410.0 8992.0 NaN NaN 1984 5655.0 NaN NaN NaN
When another dimension is added, such as an additional column, the Triangle becomes multidimensional. In this case, printing displays the Triangle’s metadata rather than its contents.
df = pd.DataFrame( data={ 'origin': [1981, 1981, 1981, 1981, 1982, 1982, 1982, 1983, 1983, 1984], 'development': [1981, 1982, 1983, 1984, 1982, 1983, 1984, 1983, 1984, 1984], 'reported': [5012, 8269, 10907, 11805, 106, 4285, 5396, 3410, 8992, 5655], 'paid': [2506, 4135, 5454, 5903, 53, 2143, 2698, 1705, 4496, 2828], } ) tr = cl.Triangle( data=df, origin='origin', development='development', columns=['reported', 'paid'], cumulative=True, ) print(tr)
Triangle Summary Valuation: 1984-12 Grain: OYDY Shape: (1, 2, 4, 4) Index: [Total] Columns: [reported, paid]
Using the
indexparameter creates a multi-dimensional Triangle split by a categorical grouping, for example Line of Business.df = pd.DataFrame( data={ 'lob': ['auto', 'auto', 'auto', 'home', 'home', 'home'], 'origin': [2020, 2020, 2021, 2020, 2020, 2021], 'development': [2020, 2021, 2021, 2020, 2021, 2021], 'reported': [100, 150, 80, 200, 280, 160], } ) tr = cl.Triangle( data=df, origin='origin', development='development', columns=['reported'], index=['lob'], cumulative=True, ) print(tr)
Triangle Summary Valuation: 2021-12 Grain: OYDY Shape: (2, 1, 2, 2) Index: [lob] Columns: [reported]
Non-standard date strings can be parsed by specifying
origin_formatanddevelopment_formatusing Pythonstrftimecodes.df = pd.DataFrame( data={ 'origin': ['2020-01', '2020-01', '2020-02', '2020-02'], 'development': ['2020-01', '2020-02', '2020-02', '2020-03'], 'reported': [100, 150, 200, 280], } ) tr = cl.Triangle( data=df, origin='origin', origin_format='%Y-%m', development='development', development_format='%Y-%m', columns=['reported'], cumulative=True, ) print(tr)
1 2 3 2020-01 100.0 150.0 NaN 2020-02 200.0 280.0 NaN 2020-03 NaN NaN NaN
Setting
cumulative=Falsebuilds an incremental Triangle, where each cell is the amount accrued within that development period rather than the cumulative total to date.df = pd.DataFrame( data={ 'origin': [1981, 1981, 1981, 1981, 1982, 1982, 1982, 1983, 1983, 1984], 'development': [1981, 1982, 1983, 1984, 1982, 1983, 1984, 1983, 1984, 1984], 'reported': [5012, 3257, 2638, 898, 106, 4179, 1111, 3410, 5582, 5655], } ) tr = cl.Triangle( data=df, origin='origin', development='development', columns=['reported'], cumulative=False, ) print(tr)
12 24 36 48 1981 5012.0 3257.0 2638.0 898.0 1982 106.0 4179.0 1111.0 NaN 1983 3410.0 5582.0 NaN NaN 1984 5655.0 NaN NaN NaN
By default (
trailing=False), chainladder uses December as the fiscal period end, so origin dates are assigned to calendar quarters. Settingtrailing=Trueinstead infers the period end from the data itself, producing quarters aligned to the origin dates.df = pd.DataFrame( data={ 'origin': ['2023-05', '2023-08', '2023-11', '2024-02'], 'development': ['2024-04', '2024-04', '2024-04', '2024-04'], 'premium': [100, 130, 160, 140], } ) tr = cl.Triangle( data=df, origin='origin', origin_format='%Y-%m', development='development', development_format='%Y-%m', columns=['premium'], cumulative=True, trailing=False, ) print(tr)
2024-04 2023Q2 100.0 2023Q3 130.0 2023Q4 160.0 2024Q1 140.0 2024Q2 NaN
tr = cl.Triangle( data=df, origin='origin', origin_format='%Y-%m', development='development', development_format='%Y-%m', columns=['premium'], cumulative=True, trailing=True, ) print(tr)
2024Q2 2024Q1 100.0 2024Q2 130.0 2024Q3 160.0 2024Q4 140.0
- cum_to_incr(inplace=False)[source]#
Method to convert an cumlative triangle into a incremental triangle.
- Parameters:
- inplace: bool
Set to True will update the instance data attribute inplace
- Returns:
- Updated instance of triangle accumulated along the origin
Examples
cl.load_sample('ukmotor')is a cumulative Triangle.cum_to_incrdifferences each cell against the prior development period, returning per-period increments.tr = cl.load_sample('ukmotor') print(tr.cum_to_incr())
12 24 36 48 60 72 84 2007 3511.0 3215.0 2266.0 1712.0 1059.0 587.0 340.0 2008 4001.0 3702.0 2278.0 1180.0 956.0 629.0 NaN 2009 4355.0 3932.0 1946.0 1522.0 1238.0 NaN NaN 2010 4295.0 3455.0 2023.0 1320.0 NaN NaN NaN 2011 4150.0 3747.0 2320.0 NaN NaN NaN NaN 2012 5102.0 4548.0 NaN NaN NaN NaN NaN 2013 6283.0 NaN NaN NaN NaN NaN NaN
- dev_to_val(inplace=False)[source]#
Converts triangle from a development lag triangle to a valuation triangle.
- Parameters:
- inplacebool
Whether to mutate the existing Triangle instance or return a new one.
- Returns:
- Triangle
Updated instance of the triangle with valuation periods.
Examples
cl.load_sample('ukmotor')is a 7x7 cumulative Triangle in development form. Each column represents months of development from the origin year.tr = cl.load_sample('ukmotor') print(tr)
12 24 36 48 60 72 84 2007 3511.0 6726.0 8992.0 10704.0 11763.0 12350.0 12690.0 2008 4001.0 7703.0 9981.0 11161.0 12117.0 12746.0 NaN 2009 4355.0 8287.0 10233.0 11755.0 12993.0 NaN NaN 2010 4295.0 7750.0 9773.0 11093.0 NaN NaN NaN 2011 4150.0 7897.0 10217.0 NaN NaN NaN NaN 2012 5102.0 9650.0 NaN NaN NaN NaN NaN 2013 6283.0 NaN NaN NaN NaN NaN NaN
Calling
dev_to_valreshapes the columns from development lags to valuation periods, so each column corresponds to a calendar year.print(tr.dev_to_val())
2007 2008 2009 2010 2011 2012 2013 2007 3511.0 6726.0 8992.0 10704.0 11763.0 12350.0 12690.0 2008 NaN 4001.0 7703.0 9981.0 11161.0 12117.0 12746.0 2009 NaN NaN 4355.0 8287.0 10233.0 11755.0 12993.0 2010 NaN NaN NaN 4295.0 7750.0 9773.0 11093.0 2011 NaN NaN NaN NaN 4150.0 7897.0 10217.0 2012 NaN NaN NaN NaN NaN 5102.0 9650.0 2013 NaN NaN NaN NaN NaN NaN 6283.0
- development_correlation(p_critical=0.5)[source]#
Mack (1997) test for correlations between subsequent development factors. Results should be within confidence interval range otherwise too much correlation
- Parameters:
- p_critical: float (default=0.10)
Value between 0 and 1 representing the confidence level for the test. A value of 0.1 implies 90% confidence.
- Returns
- ——-
DevelopmentCorrelation object with t, t_critical, t_expectation, t_variance, and range attributes.
Examples
tr = cl.load_sample('raa') dc = tr.development_correlation() print(bool(dc.t_critical.iloc[0, 0]))
False
t_criticalreports whether the calculated rank correlation falls outside the no-correlation confidence interval.Falseindicates the development factors are not significantly correlated.
- grain(grain='', trailing=False, inplace=False)[source]#
Changes the grain of a cumulative triangle.
- Parameters:
- grainstr
The grain to which you want your triangle converted, specified as ‘OXDY’ where X and Y can take on values of
['Y', 'S', 'Q', 'M' ]For example, ‘OYDY’ for Origin Year/Development Year, ‘OQDM’ for Origin quarter/Development Month, etc.- trailingbool
For partial origin years/quarters, trailing will set the year/quarter end to that of the latest available from the origin data.
- inplacebool
Whether to mutate the existing Triangle instance or return a new one.
- Returns:
- Triangle
Examples
Build a quarterly origin / quarterly development Triangle (OQDQ).
import pandas as pd df = pd.DataFrame( data={ 'origin': [ '2022Q1', '2022Q1', '2022Q1', '2022Q1', '2022Q1', '2022Q1', '2022Q1', '2022Q1', '2022Q2', '2022Q2', '2022Q2', '2022Q2', '2022Q2', '2022Q2', '2022Q2', '2022Q3', '2022Q3', '2022Q3', '2022Q3', '2022Q3', '2022Q3', '2022Q4', '2022Q4', '2022Q4', '2022Q4', '2022Q4', '2023Q1', '2023Q1', '2023Q1', '2023Q1', '2023Q2', '2023Q2', '2023Q2', '2023Q3', '2023Q3', '2023Q4', ], 'development': [ '2022Q1', '2022Q2', '2022Q3', '2022Q4', '2023Q1', '2023Q2', '2023Q3', '2023Q4', '2022Q2', '2022Q3', '2022Q4', '2023Q1', '2023Q2', '2023Q3', '2023Q4', '2022Q3', '2022Q4', '2023Q1', '2023Q2', '2023Q3', '2023Q4', '2022Q4', '2023Q1', '2023Q2', '2023Q3', '2023Q4', '2023Q1', '2023Q2', '2023Q3', '2023Q4', '2023Q2', '2023Q3', '2023Q4', '2023Q3', '2023Q4', '2023Q4', ], 'reported': [ 100, 200, 300, 400, 480, 540, 580, 600, 110, 220, 320, 420, 500, 560, 600, 120, 240, 350, 450, 520, 580, 130, 250, 370, 470, 540, 140, 260, 380, 480, 150, 270, 390, 160, 280, 170, ], } ) tr = cl.Triangle( data=df, origin='origin', development='development', columns=['reported'], cumulative=True, ) print(tr)
3 6 9 12 15 18 21 24 2022Q1 100.0 200.0 300.0 400.0 480.0 540.0 580.0 600.0 2022Q2 110.0 220.0 320.0 420.0 500.0 560.0 600.0 NaN 2022Q3 120.0 240.0 350.0 450.0 520.0 580.0 NaN NaN 2022Q4 130.0 250.0 370.0 470.0 540.0 NaN NaN NaN 2023Q1 140.0 260.0 380.0 480.0 NaN NaN NaN NaN 2023Q2 150.0 270.0 390.0 NaN NaN NaN NaN NaN 2023Q3 160.0 280.0 NaN NaN NaN NaN NaN NaN 2023Q4 170.0 NaN NaN NaN NaN NaN NaN NaN
Convert to annual origin / annual development. Origins are summed within each calendar year and development periods are aggregated to year-end.
print(tr.grain('OYDY'))
12 24 2022 1090.0 2320.0 2023 1320.0 NaN
Convert origin to annual but keep development quarterly (
OYDQ).print(tr.grain('OYDQ'))
3 6 9 12 15 18 21 24 2022 100.0 310.0 640.0 1090.0 1500.0 1860.0 2130.0 2320.0 2023 140.0 410.0 810.0 1320.0 NaN NaN NaN NaN
- incr_to_cum(inplace=False)[source]#
Method to convert an incremental triangle into a cumulative triangle.
- Parameters:
- inplace: bool
Set to True will update the instance data attribute inplace
- Returns:
- Updated instance of triangle accumulated along the origin
Examples
Construct an incremental triangle and accumulate it along the development axis.
df = pd.DataFrame( data={ 'origin': [1981, 1981, 1981, 1981, 1982, 1982, 1982, 1983, 1983, 1984], 'development': [1981, 1982, 1983, 1984, 1982, 1983, 1984, 1983, 1984, 1984], 'reported': [5012, 3257, 2638, 898, 106, 4179, 1111, 3410, 5582, 5655], } ) tr = cl.Triangle( data=df, origin='origin', development='development', columns=['reported'], cumulative=False, ) print(tr)
12 24 36 48 1981 5012.0 3257.0 2638.0 898.0 1982 106.0 4179.0 1111.0 NaN 1983 3410.0 5582.0 NaN NaN 1984 5655.0 NaN NaN NaN
print(tr.incr_to_cum())
12 24 36 48 1981 5012.0 8269.0 10907.0 11805.0 1982 106.0 4285.0 5396.0 NaN 1983 3410.0 8992.0 NaN NaN 1984 5655.0 NaN NaN NaN
By default
incr_to_cumreturns a new Triangle. Passinplace=Trueto mutate the calling Triangle instead.print(tr.is_cumulative)
False
tr.incr_to_cum(inplace=True) print(tr.is_cumulative)
True
- shift(periods=-1, axis=3)[source]#
Shift elements along an axis by desired number of periods.
Data that falls beyond the existing shape of the Triangle is eliminated and new cells default to zero.
- Parameters:
- periodsint
Number of periods to shift. Can be positive or negative.
- axis{2 or ‘origin’, 3 or ‘development’, None}, default 3
Shift direction.
- Returns:
- Triangle
updated with shifted elements
Examples
import pandas as pd df = pd.DataFrame( data={ 'origin': [2020, 2020, 2020, 2021, 2021, 2022], 'development': [2020, 2021, 2022, 2021, 2022, 2022], 'reported': [100, 200, 300, 110, 220, 120], } ) tr = cl.Triangle( data=df, origin='origin', development='development', columns=['reported'], cumulative=True, ) print(tr)
12 24 36 2020 100.0 200.0 300.0 2021 110.0 220.0 NaN 2022 120.0 NaN NaN
Shift one period along the development axis (the default). Values move right by one column and the leading column is filled with zeros.
print(tr.shift())
12 24 36 2020 0.0 100.0 200.0 2021 0.0 110.0 220.0 2022 0.0 120.0 NaN
Shift one period along the origin axis. Each origin row’s data moves down by one and the first origin row is zeroed out.
print(tr.shift(periods=-1, axis='origin'))
12 24 36 2020 0.0 0.0 0.0 2021 100.0 200.0 300.0 2022 110.0 220.0 NaN
- sort_axis(axis)[source]#
Method to sort a Triangle along a given axis
- Parameters:
- axisint or str
The axis on which to sort. May be specified as an integer (
0,1,2,3) or by name ('index','columns','origin','development').
- Returns:
- Triangle
New Triangle with the requested axis sorted in ascending order.
Examples
Build a Triangle with two columns supplied in non-alphabetical order.
df = pd.DataFrame( data={ 'origin': [2020, 2020, 2021, 2021], 'development': [2020, 2021, 2021, 2021], 'reported': [100, 200, 110, 110], 'paid': [50, 100, 60, 60], } ) tr = cl.Triangle( data=df, origin='origin', development='development', columns=['reported', 'paid'], cumulative=True, ) print(list(tr.columns))
['reported', 'paid']
Sorting on the columns axis returns a new Triangle with columns in alphabetical order.
print(list(tr.sort_axis('columns').columns))
['paid', 'reported']
- trend(trend=0.0, axis='origin', start=None, end=None, ultimate_lag=None, **kwargs)[source]#
Allows for the trending of a Triangle object along either a valuation or origin axis. This method trends using days and assumes a years is 365.25 days long.
- Parameters:
- trendfloat
The annual amount of the trend. Use 1/(1+trend)-1 to detrend.
- axisstr (options: [‘origin’, ‘valuation’])
The axis on which to apply the trend
- start: date
The start date from which trend should be calculated. If none is provided then the latest date of the triangle is used.
- end: date
The end date to which the trend should be calculated. If none is provided then the earliest period of the triangle is used.
- ultimate_lagint
If ultimate valuations are in the triangle, optionally set the overall age (in months) of the ultimate to be some lag from the latest non-Ultimate development
- Returns:
- Triangle
updated with multiplicative trend applied.
Examples
import pandas as pd df = pd.DataFrame( data={ 'origin': [2020, 2020, 2020, 2021, 2021, 2022], 'development': [2020, 2021, 2022, 2021, 2022, 2022], 'reported': [100, 200, 300, 110, 220, 120], } ) tr = cl.Triangle( data=df, origin='origin', development='development', columns=['reported'], cumulative=True, ) print(tr)
12 24 36 2020 100.0 200.0 300.0 2021 110.0 220.0 NaN 2022 120.0 NaN NaN
Apply a 10% annual trend along the origin axis. The latest origin year (2022) is unchanged; older origins are scaled up by
1.10per year of distance from the latest origin.print(tr.trend(0.10, axis='origin'))
12 24 36 2020 121.0 242.0 363.0 2021 121.0 242.0 NaN 2022 120.0 NaN NaN
Apply a 10% annual trend along the valuation axis instead. The latest diagonal is unchanged and earlier diagonals are scaled up.
print(tr.trend(0.10, axis='valuation'))
12 24 36 2020 121.0 220.0 300.0 2021 121.0 220.0 NaN 2022 120.0 NaN NaN
- val_to_dev(inplace=False)[source]#
Converts triangle from a valuation triangle to a development lag triangle.
- Parameters:
- inplacebool
Whether to mutate the existing Triangle instance or return a new one.
- Returns:
- Updated instance of triangle with development lags
Examples
val_to_devis the inverse ofdev_to_val. Round-tripping a development triangle through valuation form and back returns the original layout.tr = cl.load_sample('ukmotor') print(tr.dev_to_val().val_to_dev())
12 24 36 48 60 72 84 2007 3511.0 6726.0 8992.0 10704.0 11763.0 12350.0 12690.0 2008 4001.0 7703.0 9981.0 11161.0 12117.0 12746.0 NaN 2009 4355.0 8287.0 10233.0 11755.0 12993.0 NaN NaN 2010 4295.0 7750.0 9773.0 11093.0 NaN NaN NaN 2011 4150.0 7897.0 10217.0 NaN NaN NaN NaN 2012 5102.0 9650.0 NaN NaN NaN NaN NaN 2013 6283.0 NaN NaN NaN NaN NaN NaN
- valuation_correlation(p_critical=0.1, total=False)[source]#
Mack test for calendar year effect A calendar period has impact across developments if the probability of the number of small (or large) development factors in that period occurring randomly is less than p_critical
- Parameters:
- p_critical: float (default=0.10)
Value between 0 and 1 representing the confidence level for the test
- total:
Whether to calculate valuation correlation in total across all years (True) consistent with Mack 1993 or for each year separately (False) consistent with Mack 1997.
- Returns
- ——-
ValuationCorrelation object with z, z_critical, z_expectation and z_variance attributes.
Examples
tr = cl.load_sample('raa') vc = tr.valuation_correlation() print(vc.z_critical)
1982 1983 1984 1985 1986 1987 1988 1989 1990 1981 False False False False False False False False False
Each cell of
z_criticalflags whether the calendar-period z-statistic for that valuation falls outside the no-effect confidence interval.Falseeverywhere means no calendar period shows a significant large-or-small bias on its diagonal.
Inherited Methods
|
Append rows of other to the end of caller, returning a new object. |
|
Copy of the array, cast to a specified type. |
|
|
|
Refer to pandas for |
|
Refer to pandas for |
|
Refer to pandas for |
|
Drop specified labels from rows or columns. |
|
Refer to pandas for |
|
Method that removes origin/development vectors from edge of a triangle that are all missing values. |
|
|
|
Fill nan with 'value' by axis. |
|
Fill nan with 0 by axis. |
|
Returns the module pertaining to the backend underlying the supplied array. |
|
Group Triangle by index values. |
|
|
|
Color the background in a gradient according to the data in each column (optionally row). |
|
Passthrough of pandas functionality |
|
|
|
Refer to pandas for |
|
|
|
Refer to pandas for |
|
Refer to pandas for |
|
Refer to pandas for |
|
Refer to pandas for |
|
|
|
Refer to pandas for |
|
|
|
Refer to pandas for |
|
Passthrough of pandas functionality |
|
Refer to pandas for |
|
Refer to pandas for |
|
Alter axes labels. |
|
|
|
Converts triangle array_backend. |
|
|
|
|
|
Refer to pandas for |
|
Refer to pandas for |
|
|
|
Refer to pandas for |
|
Refer to pandas for |
|
Refer to pandas for |
|
Refer to pandas for |
|
Converts a triangle to a pandas.DataFrame. |
|
Refer to pandas for |
|
Serializes triangle object to json format |
|
Serializes triangle object to pickle. |
|
Refer to pandas for |
|
Refer to pandas for |
|
Mimics xs from pandas. |