1
0
mirror of https://github.com/polakowo/vectorbt.git synced 2022-03-22 01:31:39 +03:00

Fix broadcasting of index with the same values but different names

This commit is contained in:
Oleg Polakow
2022-02-04 20:43:47 +01:00
parent 3d7944ee8e
commit 4349182488
2 changed files with 27 additions and 6 deletions

View File

@@ -1575,6 +1575,28 @@ class TestReshapeFns:
)
)
broadcasted = reshape_fns.broadcast(
pd.DataFrame([[1, 2, 3]], columns=pd.Index(['a', 'b', 'c'], name='i1')),
pd.DataFrame([[4, 5, 6]], columns=pd.Index(['a', 'b', 'c'], name='i2')),
index_from='stack',
columns_from='stack',
drop_duplicates=True,
drop_redundant=True,
ignore_sr_names=True
)
pd.testing.assert_frame_equal(
broadcasted[0],
pd.DataFrame([[1, 2, 3]], columns=pd.MultiIndex.from_tuples([
('a', 'a'), ('b', 'b'), ('c', 'c')
], names=['i1', 'i2']))
)
pd.testing.assert_frame_equal(
broadcasted[1],
pd.DataFrame([[4, 5, 6]], columns=pd.MultiIndex.from_tuples([
('a', 'a'), ('b', 'b'), ('c', 'c')
], names=['i1', 'i2']))
)
def test_broadcast_keep(self):
# 1d
to_broadcast = 0, a1, a2, sr_none, sr1, sr2

View File

@@ -221,7 +221,7 @@ def broadcast_index(args: tp.Sequence[tp.AnyArray],
if checks.is_pandas(arg):
index = index_fns.get_index(arg, axis)
if last_index is not None:
if not pd.Index.equals(index, last_index):
if not checks.is_index_equal(index, last_index):
index_conflict = True
last_index = index
continue
@@ -241,18 +241,17 @@ def broadcast_index(args: tp.Sequence[tp.AnyArray],
if new_index is None:
new_index = index
else:
if checks.is_index_equal(index, new_index):
continue
if index_from.lower() == 'strict':
# If pandas objects have different index/columns, raise an exception
if not pd.Index.equals(index, new_index):
raise ValueError(
f"Broadcasting {index_str} is not allowed when {index_str}_from=strict")
raise ValueError(
f"Broadcasting {index_str} is not allowed when {index_str}_from=strict")
# Broadcasting index must follow the rules of a regular broadcasting operation
# https://docs.scipy.org/doc/numpy/user/basics.broadcasting.html#general-broadcasting-rules
# 1. rule: if indexes are of the same length, they are simply stacked
# 2. rule: if index has one element, it gets repeated and then stacked
if pd.Index.equals(index, new_index):
continue
if len(index) != len(new_index):
if len(index) > 1 and len(new_index) > 1:
raise ValueError("Indexes could not be broadcast together")