Skip to content

Commit 649d838

Browse files
committed
Revert "Revert FrozenList changes (doc build slowdown, pandas-dev#15559)"
This reverts commit d652485.
1 parent d652485 commit 649d838

File tree

10 files changed

+67
-22
lines changed

10 files changed

+67
-22
lines changed

doc/source/groupby.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,16 @@ We could naturally group by either the ``A`` or ``B`` columns or both:
126126
grouped = df.groupby('A')
127127
grouped = df.groupby(['A', 'B'])
128128
129+
.. versionadded:: 0.20
130+
131+
If we also have a MultiIndex on columns ``A`` and ``B``, we can group by all
132+
but the specified columns.
133+
134+
.. ipython:: python
135+
136+
df2 = df.set_index(['A', 'B'])
137+
grouped = df2.groupby(level=df2.index.names.difference(['B'])
138+
129139
These will split the DataFrame on its index (rows). We could also split by the
130140
columns:
131141

doc/source/whatsnew/v0.20.0.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ New features
2929

3030
- Integration with the ``feather-format``, including a new top-level ``pd.read_feather()`` and ``DataFrame.to_feather()`` method, see :ref:`here <io.feather>`.
3131
- ``.str.replace`` now accepts a callable, as replacement, which is passed to ``re.sub`` (:issue:`15055`)
32+
- ``FrozenList`` has gained the ``.difference()`` setop method (:issue:`15475`)
3233

3334

3435

@@ -600,6 +601,7 @@ Deprecations
600601
- ``Series.sortlevel`` and ``DataFrame.sortlevel`` have been deprecated in favor of ``Series.sort_index`` and ``DataFrame.sort_index`` (:issue:`15099`)
601602
- importing ``concat`` from ``pandas.tools.merge`` has been deprecated in favor of imports from the ``pandas`` namespace. This should only affect explict imports (:issue:`15358`)
602603
- ``Series/DataFrame/Panel.consolidate()`` been deprecated as a public method. (:issue:`15483`)
604+
- ``FrozenList`` addition (new object and inplace) have been deprecated in favor of the ``.union()`` method. (:issue: `15475`)
603605
- The following top-level pandas functions have been deprecated and will be removed in a future version (:issue:`13790`)
604606
* ``pd.pnow()``, replaced by ``Period.now()``
605607
* ``pd.Term``, is removed, as it is not applicable to user code. Instead use in-line string expressions in the where clause when searching in HDFStore

pandas/core/panel.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -940,9 +940,9 @@ def construct_index_parts(idx, major=True):
940940
minor_labels, minor_levels, minor_names = construct_index_parts(
941941
self.minor_axis, major=False)
942942

943-
levels = major_levels + minor_levels
944-
labels = major_labels + minor_labels
945-
names = major_names + minor_names
943+
levels = list(major_levels) + list(minor_levels)
944+
labels = list(major_labels) + list(minor_labels)
945+
names = list(major_names) + list(minor_names)
946946

947947
index = MultiIndex(levels=levels, labels=labels, names=names,
948948
verify_integrity=False)

pandas/core/reshape.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,8 @@ def get_new_columns(self):
216216
width = len(self.value_columns)
217217
propagator = np.repeat(np.arange(width), stride)
218218
if isinstance(self.value_columns, MultiIndex):
219-
new_levels = self.value_columns.levels + (self.removed_level,)
220-
new_names = self.value_columns.names + (self.removed_name,)
219+
new_levels = self.value_columns.levels.union((self.removed_level,))
220+
new_names = self.value_columns.names.union((self.removed_name,))
221221

222222
new_labels = [lab.take(propagator)
223223
for lab in self.value_columns.labels]
@@ -806,7 +806,7 @@ def melt(frame, id_vars=None, value_vars=None, var_name=None,
806806
for col in id_vars:
807807
mdata[col] = np.tile(frame.pop(col).values, K)
808808

809-
mcolumns = id_vars + var_name + [value_name]
809+
mcolumns = list(id_vars) + list(var_name) + list([value_name])
810810

811811
mdata[value_name] = frame.values.ravel('F')
812812
for i, col in enumerate(var_name):

pandas/core/strings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -787,7 +787,7 @@ def str_extractall(arr, pat, flags=0):
787787
if 0 < len(index_list):
788788
from pandas import MultiIndex
789789
index = MultiIndex.from_tuples(
790-
index_list, names=arr.index.names + ["match"])
790+
index_list, names=arr.index.names.union(["match"]))
791791
else:
792792
index = None
793793
result = arr._constructor_expanddim(match_list, index=index,

pandas/indexes/frozen.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
from pandas.types.cast import _coerce_indexer_dtype
1414
from pandas.formats.printing import pprint_thing
1515

16+
import warnings
17+
1618

1719
class FrozenList(PandasObject, list):
1820

@@ -25,11 +27,14 @@ class FrozenList(PandasObject, list):
2527
# typechecks
2628

2729
def __add__(self, other):
30+
warnings.warn("__add__ is deprecated, use union(...)", FutureWarning)
31+
return self.union(other)
32+
33+
def __iadd__(self, other):
34+
warnings.warn("__iadd__ is deprecated, use union(...)", FutureWarning)
2835
if isinstance(other, tuple):
2936
other = list(other)
30-
return self.__class__(super(FrozenList, self).__add__(other))
31-
32-
__iadd__ = __add__
37+
return super(FrozenList, self).__iadd__(other)
3338

3439
# Python 2 compat
3540
def __getslice__(self, i, j):
@@ -80,6 +85,19 @@ def __repr__(self):
8085
__setitem__ = __setslice__ = __delitem__ = __delslice__ = _disabled
8186
pop = append = extend = remove = sort = insert = _disabled
8287

88+
def union(self, other):
89+
"""Returns a FrozenList with other concatenated to the end of self"""
90+
if isinstance(other, tuple):
91+
other = list(other)
92+
return self.__class__(super(FrozenList, self).__add__(other))
93+
94+
def difference(self, other):
95+
"""Returns a FrozenList with the same elements as self, but with elements
96+
that are also in other removed."""
97+
other = set(other)
98+
temp = [x for x in self if x not in other]
99+
return self.__class__(temp)
100+
83101

84102
class FrozenNDArray(PandasObject, np.ndarray):
85103

pandas/tests/groupby/test_value_counts.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def check_value_counts(df, keys, bins):
2828

2929
gr = df.groupby(keys, sort=isort)
3030
right = gr['3rd'].apply(Series.value_counts, **kwargs)
31-
right.index.names = right.index.names[:-1] + ['3rd']
31+
right.index.names = right.index.names[:-1].union(['3rd'])
3232

3333
# have to sort on index because of unstable sort on values
3434
left, right = map(rebuild_index, (left, right)) # xref GH9212

pandas/tests/indexes/test_frozen.py

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,35 @@ def setUp(self):
1515
self.klass = FrozenList
1616

1717
def test_add(self):
18-
result = self.container + (1, 2, 3)
18+
q = FrozenList([1])
19+
with tm.assert_produces_warning(FutureWarning,
20+
check_stacklevel=False):
21+
q = q + [2, 3]
22+
expected = FrozenList([1, 2, 3])
23+
self.check_result(q, expected)
24+
25+
def test_iadd(self):
26+
q = FrozenList([1])
27+
with tm.assert_produces_warning(FutureWarning,
28+
check_stacklevel=False):
29+
q += [2, 3]
30+
expected = FrozenList([1, 2, 3])
31+
self.check_result(q, expected)
32+
33+
def test_union(self):
34+
result = self.container.union((1, 2, 3))
1935
expected = FrozenList(self.lst + [1, 2, 3])
2036
self.check_result(result, expected)
2137

22-
result = (1, 2, 3) + self.container
23-
expected = FrozenList([1, 2, 3] + self.lst)
38+
def test_difference(self):
39+
result = self.container.difference([2])
40+
expected = FrozenList([1, 3, 4, 5])
2441
self.check_result(result, expected)
2542

26-
def test_inplace(self):
27-
q = r = self.container
28-
q += [5]
29-
self.check_result(q, self.lst + [5])
30-
# other shouldn't be mutated
31-
self.check_result(r, self.lst)
43+
def test_difference_dupe(self):
44+
result = FrozenList([1, 2, 3, 2]).difference([2])
45+
expected = FrozenList([1, 3])
46+
self.check_result(result, expected)
3247

3348

3449
class TestFrozenNDArray(CheckImmutable, CheckStringMixin, tm.TestCase):

pandas/tools/concat.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@ def _make_concat_multiindex(indexes, keys, levels=None, names=None):
574574
" not have the same number of levels")
575575

576576
# also copies
577-
names = names + _get_consensus_names(indexes)
577+
names = list(names) + list(_get_consensus_names(indexes))
578578

579579
return MultiIndex(levels=levels, labels=label_list, names=names,
580580
verify_integrity=False)

test_fast.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
# https://github.com/pytest-dev/pytest/issues/1075
66
export PYTHONHASHSEED=$(python -c 'import random; print(random.randint(1, 4294967295))')
77

8-
pytest pandas --skip-slow --skip-network -m "not single" -n 4
8+
pytest pandas --skip-slow --skip-network -m "not single" -n 4 $@

0 commit comments

Comments
 (0)