From 8915c5c7e08089d39f6d19fcabf717fa3557d217 Mon Sep 17 00:00:00 2001 From: tp Date: Wed, 17 Apr 2019 00:01:46 +0100 Subject: [PATCH 1/4] DEPR: deprecate (DataFrame|Series).iteritems --- asv_bench/benchmarks/frame_methods.py | 8 +++---- .../development/contributing_docstring.rst | 2 +- doc/source/getting_started/basics.rst | 8 +++---- doc/source/reference/frame.rst | 2 +- doc/source/reference/series.rst | 1 - doc/source/whatsnew/v0.25.0.rst | 2 ++ pandas/core/frame.py | 22 ++++++++++--------- pandas/core/generic.py | 17 ++++++++------ pandas/core/indexes/multi.py | 2 +- pandas/core/reshape/pivot.py | 2 +- pandas/core/reshape/reshape.py | 8 +++---- pandas/core/series.py | 13 ++++++----- pandas/core/sparse/frame.py | 2 +- pandas/core/strings.py | 2 +- pandas/core/util/hashing.py | 2 +- pandas/io/formats/style.py | 2 +- pandas/io/json/_json.py | 2 +- pandas/io/json/_table_schema.py | 2 +- pandas/io/msgpack/_packer.pyx | 2 +- pandas/io/sql.py | 2 +- pandas/io/stata.py | 4 ++-- pandas/plotting/_matplotlib/core.py | 2 +- pandas/tests/frame/test_api.py | 4 ++-- pandas/tests/frame/test_indexing.py | 2 +- pandas/tests/frame/test_operators.py | 4 ++-- pandas/tests/indexing/test_indexing.py | 2 +- pandas/tests/indexing/test_scalar.py | 4 ++-- pandas/tests/io/test_html.py | 4 ++-- pandas/tests/series/test_api.py | 4 ++-- pandas/tests/series/test_io.py | 2 +- pandas/tests/test_base.py | 4 ++-- 31 files changed, 73 insertions(+), 66 deletions(-) diff --git a/asv_bench/benchmarks/frame_methods.py b/asv_bench/benchmarks/frame_methods.py index 5008b77d9fb28..e2f6764c76eef 100644 --- a/asv_bench/benchmarks/frame_methods.py +++ b/asv_bench/benchmarks/frame_methods.py @@ -115,15 +115,15 @@ def setup(self): ) self.df4 = DataFrame(np.random.randn(N * 1000, 10)) - def time_iteritems(self): + def time_items(self): # (monitor no-copying behaviour) if hasattr(self.df, "_item_cache"): self.df._item_cache.clear() - for name, col in self.df.iteritems(): + for name, col in self.df.items(): pass - def time_iteritems_cached(self): - for name, col in self.df.iteritems(): + def time_items_cached(self): + for name, col in self.df.items(): pass def time_iteritems_indexing(self): diff --git a/doc/source/development/contributing_docstring.rst b/doc/source/development/contributing_docstring.rst index 62216f168af3c..34bc5f44eb0c0 100644 --- a/doc/source/development/contributing_docstring.rst +++ b/doc/source/development/contributing_docstring.rst @@ -522,7 +522,7 @@ examples: * ``loc`` and ``iloc``, as they do the same, but in one case providing indices and in the other positions * ``max`` and ``min``, as they do the opposite -* ``iterrows``, ``itertuples`` and ``iteritems``, as it is easy that a user +* ``iterrows``, ``itertuples`` and ``items``, as it is easy that a user looking for the method to iterate over columns ends up in the method to iterate over rows, and vice-versa * ``fillna`` and ``dropna``, as both methods are used to handle missing values diff --git a/doc/source/getting_started/basics.rst b/doc/source/getting_started/basics.rst index 682d6c1ef8301..3463e267553e9 100644 --- a/doc/source/getting_started/basics.rst +++ b/doc/source/getting_started/basics.rst @@ -1475,7 +1475,7 @@ Thus, for example, iterating over a DataFrame gives you the column names: print(col) -Pandas objects also have the dict-like :meth:`~DataFrame.iteritems` method to +Pandas objects also have the dict-like :meth:`~DataFrame.items` method to iterate over the (key, value) pairs. To iterate over the rows of a DataFrame, you can use the following methods: @@ -1524,10 +1524,10 @@ To iterate over the rows of a DataFrame, you can use the following methods: df -iteritems +items ~~~~~~~~~ -Consistent with the dict-like interface, :meth:`~DataFrame.iteritems` iterates +Consistent with the dict-like interface, :meth:`~DataFrame.items` iterates through key-value pairs: * **Series**: (index, scalar value) pairs @@ -1537,7 +1537,7 @@ For example: .. ipython:: python - for label, ser in df.iteritems(): + for label, ser in df.items(): print(label) print(ser) diff --git a/doc/source/reference/frame.rst b/doc/source/reference/frame.rst index 1a316c2f25ec6..f99e7ce928237 100644 --- a/doc/source/reference/frame.rst +++ b/doc/source/reference/frame.rst @@ -68,7 +68,7 @@ Indexing, iteration DataFrame.__iter__ DataFrame.items DataFrame.keys - DataFrame.iteritems + DataFrame.items DataFrame.iterrows DataFrame.itertuples DataFrame.lookup diff --git a/doc/source/reference/series.rst b/doc/source/reference/series.rst index e8e2f64e22cb5..b3bdc0b193f70 100644 --- a/doc/source/reference/series.rst +++ b/doc/source/reference/series.rst @@ -76,7 +76,6 @@ Indexing, iteration Series.loc Series.iloc Series.__iter__ - Series.iteritems Series.items Series.keys Series.pop diff --git a/doc/source/whatsnew/v0.25.0.rst b/doc/source/whatsnew/v0.25.0.rst index daca08d69346d..3eaf409286e2d 100644 --- a/doc/source/whatsnew/v0.25.0.rst +++ b/doc/source/whatsnew/v0.25.0.rst @@ -886,9 +886,11 @@ Other deprecations - :meth:`Index.item` and :meth:`Series.item` is deprecated. (:issue:`18262`) - The default value ``ordered=None`` in :class:`~pandas.api.types.CategoricalDtype` has been deprecated in favor of ``ordered=False``. When converting between categorical types ``ordered=True`` must be explicitly passed in order to be preserved. (:issue:`26336`) - :meth:`Index.contains` is deprecated. Use ``key in index`` (``__contains__``) instead (:issue:`17753`). +- ``DataFrame.iteritems`` and ``Series.iteritems`` have been deprecated. :attr:`DataFrame.items` and :attr:`Series.items` provide the exact same functionality and should be used instead (:issue:`26114`). - :meth:`DataFrame.get_dtype_counts` is deprecated. (:issue:`18262`) - :meth:`Categorical.ravel` will return a :class:`Categorical` instead of a ``np.ndarray`` (:issue:`27199`) + .. _whatsnew_0250.prior_deprecations: Removal of prior version deprecations/changes diff --git a/pandas/core/frame.py b/pandas/core/frame.py index ce1b99b315936..14d5c5767a601 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -771,7 +771,7 @@ def style(self): return Styler(self) - def iteritems(self): + def items(self): r""" Iterator over (column name, Series) pairs. @@ -802,7 +802,7 @@ def iteritems(self): panda bear 1864 polar bear 22000 koala marsupial 80000 - >>> for label, content in df.iteritems(): + >>> for label, content in df.items(): ... print('label:', label) ... print('content:', content, sep='\n') ... @@ -826,6 +826,10 @@ def iteritems(self): for i, k in enumerate(self.columns): yield k, self._ixs(i, axis=1) + @Appender(items.__doc) + def iteritems(self): + return self.items() + def iterrows(self): """ Iterate over DataFrame rows as (index, Series) pairs. @@ -843,7 +847,7 @@ def iterrows(self): See Also -------- itertuples : Iterate over DataFrame rows as namedtuples of the values. - iteritems : Iterate over (column name, Series) pairs. + items : Iterate over (column name, Series) pairs. Notes ----- @@ -901,7 +905,7 @@ def itertuples(self, index=True, name="Pandas"): -------- DataFrame.iterrows : Iterate over DataFrame rows as (index, Series) pairs. - DataFrame.iteritems : Iterate over (column name, Series) pairs. + DataFrame.items : Iterate over (column name, Series) pairs. Notes ----- @@ -958,8 +962,6 @@ def itertuples(self, index=True, name="Pandas"): # fallback to regular tuples return zip(*arrays) - items = iteritems - def __len__(self): """ Returns length of info axis, but here we use the index. @@ -2634,7 +2636,7 @@ def memory_usage(self, index=True, deep=False): 5216 """ result = Series( - [c.memory_usage(index=False, deep=deep) for col, c in self.iteritems()], + [c.memory_usage(index=False, deep=deep) for col, c in self.items()], index=self.columns, ) if index: @@ -4955,7 +4957,7 @@ def f(vals): if not diff.empty: raise KeyError(diff) - vals = (col.values for name, col in self.iteritems() if name in subset) + vals = (col.values for name, col in self.items() if name in subset) labels, shape = map(list, zip(*map(f, vals))) ids = get_group_index(labels, shape, sort=False, xnull=False) @@ -7343,7 +7345,7 @@ def round(self, decimals=0, *args, **kwargs): from pandas.core.reshape.concat import concat def _dict_round(df, decimals): - for col, vals in df.iteritems(): + for col, vals in df.items(): try: yield _series_round(vals, decimals[col]) except KeyError: @@ -7363,7 +7365,7 @@ def _series_round(s, decimals): new_cols = [col for col in _dict_round(self, decimals)] elif is_integer(decimals): # Dispatch to Series.round - new_cols = [_series_round(v, decimals) for _, v in self.iteritems()] + new_cols = [_series_round(v, decimals) for _, v in self.items()] else: raise TypeError("decimals must be an integer, a dict-like or a " "Series") diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 5db06d32880cc..21a6d3cbd5745 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -494,7 +494,7 @@ def _get_space_character_free_column_resolvers(self): """ from pandas.core.computation.common import _remove_spaces_column_name - return {_remove_spaces_column_name(k): v for k, v in self.iteritems()} + return {_remove_spaces_column_name(k): v for k, v in self.items()} @property def _info_axis(self): @@ -1936,15 +1936,18 @@ def keys(self): """ return self._info_axis - def iteritems(self): - """ - Iterate over (label, values) on info axis + def items(self): + """Iterate over (label, values) on info axis - This is index for Series, columns for DataFrame and so on. + This is index for Series and columns for DataFrame. """ for h in self._info_axis: yield h, self[h] + @Appender(items.__doc__) + def iteritems(self): + return self.items() + def __len__(self): """Returns length of info axis""" return len(self._info_axis) @@ -5912,7 +5915,7 @@ def astype(self, dtype, copy=True, errors="raise", **kwargs): "key in a dtype mappings argument." ) results = [] - for col_name, col in self.iteritems(): + for col_name, col in self.items(): if col_name in dtype: results.append( col.astype( @@ -10328,7 +10331,7 @@ def describe_1d(data): else: data = self.select_dtypes(include=include, exclude=exclude) - ldesc = [describe_1d(s) for _, s in data.iteritems()] + ldesc = [describe_1d(s) for _, s in data.items()] # set a convenient order for rows names = [] ldesc_indexes = sorted((x.index for x in ldesc), key=len) diff --git a/pandas/core/indexes/multi.py b/pandas/core/indexes/multi.py index ff0bffacd37ad..670a4666a3440 100644 --- a/pandas/core/indexes/multi.py +++ b/pandas/core/indexes/multi.py @@ -601,7 +601,7 @@ def from_frame(cls, df, sortorder=None, names=None): if not isinstance(df, ABCDataFrame): raise TypeError("Input must be a DataFrame") - column_names, columns = zip(*df.iteritems()) + column_names, columns = zip(*df.items()) names = column_names if names is None else names return cls.from_arrays(columns, sortorder=sortorder, names=names) diff --git a/pandas/core/reshape/pivot.py b/pandas/core/reshape/pivot.py index 188f2edd96590..23bf89b2bc1ac 100644 --- a/pandas/core/reshape/pivot.py +++ b/pandas/core/reshape/pivot.py @@ -272,7 +272,7 @@ def _compute_grand_margin(data, values, aggfunc, margins_name="All"): if values: grand_margin = {} - for k, v in data[values].iteritems(): + for k, v in data[values].items(): try: if isinstance(aggfunc, str): grand_margin[k] = getattr(v, aggfunc)() diff --git a/pandas/core/reshape/reshape.py b/pandas/core/reshape/reshape.py index 5d932d7ded9b8..540a06caec220 100644 --- a/pandas/core/reshape/reshape.py +++ b/pandas/core/reshape/reshape.py @@ -478,7 +478,7 @@ def _unstack_extension_series(series, level, fill_value): out = [] values = extract_array(series, extract_numpy=False) - for col, indices in result.iteritems(): + for col, indices in result.items(): out.append( Series( values.take(indices.values, allow_fill=True, fill_value=fill_value), @@ -544,7 +544,7 @@ def factorize(index): if is_extension_array_dtype(dtype): arr = dtype.construct_array_type() new_values = arr._concat_same_type( - [col._values for _, col in frame.iteritems()] + [col._values for _, col in frame.items()] ) new_values = _reorder_for_extension_array_stack(new_values, N, K) else: @@ -695,7 +695,7 @@ def _convert_level_number(level_num, columns): subset = this[this.columns[loc]] value_slice = dtype.construct_array_type()._concat_same_type( - [x._values for _, x in subset.iteritems()] + [x._values for _, x in subset.items()] ) N, K = this.shape idx = np.arange(N * K).reshape(K, N).T.ravel() @@ -909,7 +909,7 @@ def check_len(item, name): # columns to prepend to result. with_dummies = [data.select_dtypes(exclude=dtypes_to_encode)] - for (col, pre, sep) in zip(data_to_encode.iteritems(), prefix, prefix_sep): + for (col, pre, sep) in zip(data_to_encode.items(), prefix, prefix_sep): # col is (column_name, column), use just column data here dummy = _get_dummies_1d( col[1], diff --git a/pandas/core/series.py b/pandas/core/series.py index b3a7f38aef8ef..ec898ed2b6f72 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -1692,13 +1692,12 @@ def to_string( # ---------------------------------------------------------------------- - def iteritems(self): + def items(self): """ Lazily iterate over (index, value) tuples. This method returns an iterable tuple (index, value). This is - convenient if you want to create a lazy iterator. Note that the - methods Series.items and Series.iteritems are the same methods. + convenient if you want to create a lazy iterator. Returns ------- @@ -1708,12 +1707,12 @@ def iteritems(self): See Also -------- - DataFrame.iteritems : Equivalent to Series.iteritems for DataFrame. + DataFrame.items : Equivalent to Series.items for DataFrame. Examples -------- >>> s = pd.Series(['A', 'B', 'C']) - >>> for index, value in s.iteritems(): + >>> for index, value in s.items(): ... print("Index : {}, Value : {}".format(index, value)) Index : 0, Value : A Index : 1, Value : B @@ -1721,7 +1720,9 @@ def iteritems(self): """ return zip(iter(self.index), iter(self)) - items = iteritems + @Appender(generic._shared_docs["iteritems"] % _shared_doc_kwargs) + def iteritems(self): + return self.items() # ---------------------------------------------------------------------- # Misc public methods diff --git a/pandas/core/sparse/frame.py b/pandas/core/sparse/frame.py index f195e4b5f4e37..ecb5dc93031ab 100644 --- a/pandas/core/sparse/frame.py +++ b/pandas/core/sparse/frame.py @@ -695,7 +695,7 @@ def _reindex_index( need_mask = mask.any() new_series = {} - for col, series in self.iteritems(): + for col, series in self.items(): if mask.all(): continue diff --git a/pandas/core/strings.py b/pandas/core/strings.py index 70700653c4795..7c293ca4e50b0 100644 --- a/pandas/core/strings.py +++ b/pandas/core/strings.py @@ -998,7 +998,7 @@ def str_extractall(arr, pat, flags=0): index_list = [] is_mi = arr.index.nlevels > 1 - for subject_key, subject in arr.iteritems(): + for subject_key, subject in arr.items(): if isinstance(subject, str): if not is_mi: diff --git a/pandas/core/util/hashing.py b/pandas/core/util/hashing.py index f07133baed435..f5ab81ad9089e 100644 --- a/pandas/core/util/hashing.py +++ b/pandas/core/util/hashing.py @@ -113,7 +113,7 @@ def hash_pandas_object( h = Series(h, index=obj.index, dtype="uint64", copy=False) elif isinstance(obj, ABCDataFrame): - hashes = (hash_array(series.values) for _, series in obj.iteritems()) + hashes = (hash_array(series.values) for _, series in obj.items()) num_items = len(obj.columns) if index: index_hash_generator = ( diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py index e7aa5d22995c6..98349fe1e4792 100644 --- a/pandas/io/formats/style.py +++ b/pandas/io/formats/style.py @@ -538,7 +538,7 @@ def _update_ctx(self, attrs): matter. """ for row_label, v in attrs.iterrows(): - for col_label, col in v.iteritems(): + for col_label, col in v.items(): i = self.index.get_indexer([row_label])[0] j = self.columns.get_indexer([col_label])[0] for pair in col.rstrip(";").split(";"): diff --git a/pandas/io/json/_json.py b/pandas/io/json/_json.py index 1f0728ee96469..f3c966bb1a476 100644 --- a/pandas/io/json/_json.py +++ b/pandas/io/json/_json.py @@ -1105,7 +1105,7 @@ def _process_converter(self, f, filt=None): needs_new_obj = False new_obj = dict() - for i, (col, c) in enumerate(self.obj.iteritems()): + for i, (col, c) in enumerate(self.obj.items()): if filt(col, c): new_data, result = f(col, c) if result: diff --git a/pandas/io/json/_table_schema.py b/pandas/io/json/_table_schema.py index 045127c63af5c..1e7cd54d9f4a0 100644 --- a/pandas/io/json/_table_schema.py +++ b/pandas/io/json/_table_schema.py @@ -249,7 +249,7 @@ def build_table_schema(data, index=True, primary_key=None, version=True): fields.append(convert_pandas_type_to_json_field(data.index)) if data.ndim > 1: - for column, s in data.iteritems(): + for column, s in data.items(): fields.append(convert_pandas_type_to_json_field(s)) else: fields.append(convert_pandas_type_to_json_field(data)) diff --git a/pandas/io/msgpack/_packer.pyx b/pandas/io/msgpack/_packer.pyx index a0d2b013c8e9d..0ed188074f3d9 100644 --- a/pandas/io/msgpack/_packer.pyx +++ b/pandas/io/msgpack/_packer.pyx @@ -194,7 +194,7 @@ cdef class Packer: raise ValueError("dict is too large") ret = msgpack_pack_map(&self.pk, L) if ret == 0: - for k, v in d.iteritems(): + for k, v in d.items(): ret = self._pack(k, nest_limit - 1) if ret != 0: break ret = self._pack(v, nest_limit - 1) diff --git a/pandas/io/sql.py b/pandas/io/sql.py index 211571c7dbaa1..6fe34e4e9705a 100644 --- a/pandas/io/sql.py +++ b/pandas/io/sql.py @@ -108,7 +108,7 @@ def _parse_date_columns(data_frame, parse_dates): # we want to coerce datetime64_tz dtypes for now to UTC # we could in theory do a 'nice' conversion from a FixedOffset tz # GH11216 - for col_name, df_col in data_frame.iteritems(): + for col_name, df_col in data_frame.items(): if is_datetime64tz_dtype(df_col) or col_name in parse_dates: try: fmt = parse_dates[col_name] diff --git a/pandas/io/stata.py b/pandas/io/stata.py index 7087d2ee963cb..29cb2a5dc0f0e 100644 --- a/pandas/io/stata.py +++ b/pandas/io/stata.py @@ -2302,7 +2302,7 @@ def _check_column_names(self, data): def _set_formats_and_types(self, data, dtypes): self.typlist = [] self.fmtlist = [] - for col, dtype in dtypes.iteritems(): + for col, dtype in dtypes.items(): self.fmtlist.append(_dtype_to_default_stata_fmt(dtype, data[col])) self.typlist.append(_dtype_to_stata_type(dtype, data[col])) @@ -3168,7 +3168,7 @@ def _convert_strls(self, data): def _set_formats_and_types(self, data, dtypes): self.typlist = [] self.fmtlist = [] - for col, dtype in dtypes.iteritems(): + for col, dtype in dtypes.items(): force_strl = col in self._convert_strl fmt = _dtype_to_default_stata_fmt( dtype, data[col], dta_version=117, force_strl=force_strl diff --git a/pandas/plotting/_matplotlib/core.py b/pandas/plotting/_matplotlib/core.py index d25715e6d167b..519465802085b 100644 --- a/pandas/plotting/_matplotlib/core.py +++ b/pandas/plotting/_matplotlib/core.py @@ -258,7 +258,7 @@ def _iter_data(self, data=None, keep_index=False, fillna=None): # else: # columns = data.columns - for col, values in data.iteritems(): + for col, values in data.items(): if keep_index is True: yield col, values else: diff --git a/pandas/tests/frame/test_api.py b/pandas/tests/frame/test_api.py index 76a210e129eb3..3c0eca297f243 100644 --- a/pandas/tests/frame/test_api.py +++ b/pandas/tests/frame/test_api.py @@ -319,7 +319,7 @@ def test_sequence_like_with_categorical(self): for row, s in df.iterrows(): str(s) - for c, col in df.iteritems(): + for c, col in df.items(): str(s) def test_len(self, float_frame): @@ -430,7 +430,7 @@ def test_repr_with_mi_nat(self, float_string_frame): expected = " X\nNaT a 1\n2013-01-01 b 2" assert result == expected - def test_iteritems_names(self, float_string_frame): + def test_items_names(self, float_string_frame): for k, v in float_string_frame.items(): assert v.name == k diff --git a/pandas/tests/frame/test_indexing.py b/pandas/tests/frame/test_indexing.py index c2d38b2938fca..3c102f49c6cbf 100644 --- a/pandas/tests/frame/test_indexing.py +++ b/pandas/tests/frame/test_indexing.py @@ -2712,7 +2712,7 @@ def _check_get(df, cond, check_dtypes=True): other1 = _safe_add(df) rs = df.where(cond, other1) rs2 = df.where(cond.values, other1) - for k, v in rs.iteritems(): + for k, v in rs.items(): exp = Series(np.where(cond[k], df[k], other1[k]), index=v.index) assert_series_equal(v, exp, check_names=False) assert_frame_equal(rs, rs2) diff --git a/pandas/tests/frame/test_operators.py b/pandas/tests/frame/test_operators.py index 67482ddf657fb..bffdf17a49750 100644 --- a/pandas/tests/frame/test_operators.py +++ b/pandas/tests/frame/test_operators.py @@ -281,7 +281,7 @@ def test_binary_ops_align(self): result = getattr(df, op)(x, level="third", axis=0) expected = pd.concat( - [opa(df.loc[idx[:, :, i], :], v) for i, v in x.iteritems()] + [opa(df.loc[idx[:, :, i], :], v) for i, v in x.items()] ).sort_index() assert_frame_equal(result, expected) @@ -289,7 +289,7 @@ def test_binary_ops_align(self): result = getattr(df, op)(x, level="second", axis=0) expected = ( - pd.concat([opa(df.loc[idx[:, i], :], v) for i, v in x.iteritems()]) + pd.concat([opa(df.loc[idx[:, i], :], v) for i, v in x.items()]) .reindex_like(df) .sort_index() ) diff --git a/pandas/tests/indexing/test_indexing.py b/pandas/tests/indexing/test_indexing.py index e06047b52ac15..ad3957138ceee 100644 --- a/pandas/tests/indexing/test_indexing.py +++ b/pandas/tests/indexing/test_indexing.py @@ -842,7 +842,7 @@ def test_float_index_non_scalar_assignment(self): def test_float_index_at_iat(self): s = Series([1, 2, 3], index=[0.1, 0.2, 0.3]) - for el, item in s.iteritems(): + for el, item in s.items(): assert s.at[el] == item for i in range(len(s)): assert s.iat[i] == i + 1 diff --git a/pandas/tests/indexing/test_scalar.py b/pandas/tests/indexing/test_scalar.py index e6ccee684b76b..38b4897e55c84 100644 --- a/pandas/tests/indexing/test_scalar.py +++ b/pandas/tests/indexing/test_scalar.py @@ -198,7 +198,7 @@ def test_series_set_tz_timestamp(self, tz_naive_fixture): def test_mixed_index_at_iat_loc_iloc_series(self): # GH 19860 s = Series([1, 2, 3, 4, 5], index=["a", "b", "c", 1, 2]) - for el, item in s.iteritems(): + for el, item in s.items(): assert s.at[el] == s.loc[el] == item for i in range(len(s)): assert s.iat[i] == s.iloc[i] == i + 1 @@ -214,7 +214,7 @@ def test_mixed_index_at_iat_loc_iloc_dataframe(self): [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]], columns=["a", "b", "c", 1, 2] ) for rowIdx, row in df.iterrows(): - for el, item in row.iteritems(): + for el, item in row.items(): assert df.at[rowIdx, el] == df.loc[rowIdx, el] == item for row in range(2): diff --git a/pandas/tests/io/test_html.py b/pandas/tests/io/test_html.py index 9752b4c62aff7..f64defc848e17 100644 --- a/pandas/tests/io/test_html.py +++ b/pandas/tests/io/test_html.py @@ -380,7 +380,7 @@ def test_thousands_macau_stats(self, datapath): dfs = self.read_html(macau_data, index_col=0, attrs={"class": "style1"}) df = dfs[all_non_nan_table_index] - assert not any(s.isna().any() for _, s in df.iteritems()) + assert not any(s.isna().any() for _, s in df.items()) @pytest.mark.slow def test_thousands_macau_index_col(self, datapath): @@ -389,7 +389,7 @@ def test_thousands_macau_index_col(self, datapath): dfs = self.read_html(macau_data, index_col=0, header=0) df = dfs[all_non_nan_table_index] - assert not any(s.isna().any() for _, s in df.iteritems()) + assert not any(s.isna().any() for _, s in df.items()) def test_empty_tables(self): """ diff --git a/pandas/tests/series/test_api.py b/pandas/tests/series/test_api.py index 2097264ba5e78..f91a1d1f2035b 100644 --- a/pandas/tests/series/test_api.py +++ b/pandas/tests/series/test_api.py @@ -336,10 +336,10 @@ def test_values(self): tm.assert_almost_equal(self.ts.values, self.ts, check_dtype=False) def test_iteritems(self): - for idx, val in self.series.items(): + for idx, val in self.series.iteritems(): assert val == self.series[idx] - for idx, val in self.ts.items(): + for idx, val in self.ts.iteritems(): assert val == self.ts[idx] # assert is lazy (genrators don't define reverse, lists do) diff --git a/pandas/tests/series/test_io.py b/pandas/tests/series/test_io.py index 0238314122462..8f79210c40d31 100644 --- a/pandas/tests/series/test_io.py +++ b/pandas/tests/series/test_io.py @@ -259,5 +259,5 @@ def test_to_dict(self, mapping, datetime_series): Series(datetime_series.to_dict(mapping), name="ts"), datetime_series ) from_method = Series(datetime_series.to_dict(collections.Counter)) - from_constructor = Series(collections.Counter(datetime_series.iteritems())) + from_constructor = Series(collections.Counter(datetime_series.items())) tm.assert_series_equal(from_method, from_constructor) diff --git a/pandas/tests/test_base.py b/pandas/tests/test_base.py index 279d6dd84d92b..d75016824d6cf 100644 --- a/pandas/tests/test_base.py +++ b/pandas/tests/test_base.py @@ -1107,13 +1107,13 @@ def test_iterable_object_and_category(self, typ, method, dtype, rdtype, obj): @pytest.mark.parametrize("dtype, rdtype", dtypes) def test_iterable_items(self, dtype, rdtype): # gh-13258 - # test items / iteritems yields the correct boxed scalars + # test if items yields the correct boxed scalars # this only applies to series s = Series([1], dtype=dtype) _, result = list(s.items())[0] assert isinstance(result, rdtype) - _, result = list(s.iteritems())[0] + _, result = list(s.items())[0] assert isinstance(result, rdtype) @pytest.mark.parametrize( From 579013260961dbe8eaabf2b65c947f04a2169f81 Mon Sep 17 00:00:00 2001 From: tp Date: Mon, 3 Jun 2019 23:06:52 +0200 Subject: [PATCH 2/4] Change header underline etc. --- doc/source/getting_started/basics.rst | 2 +- pandas/core/generic.py | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/source/getting_started/basics.rst b/doc/source/getting_started/basics.rst index 3463e267553e9..bc3b7b4c70fd1 100644 --- a/doc/source/getting_started/basics.rst +++ b/doc/source/getting_started/basics.rst @@ -1525,7 +1525,7 @@ To iterate over the rows of a DataFrame, you can use the following methods: df items -~~~~~~~~~ +~~~~~ Consistent with the dict-like interface, :meth:`~DataFrame.items` iterates through key-value pairs: diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 21a6d3cbd5745..4e05dfca43e78 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -1940,6 +1940,10 @@ def items(self): """Iterate over (label, values) on info axis This is index for Series and columns for DataFrame. + + Returns + ------- + Generator """ for h in self._info_axis: yield h, self[h] From 5307152243f63502572f8d193f9578f68f857cdf Mon Sep 17 00:00:00 2001 From: tp Date: Wed, 10 Jul 2019 08:07:10 +0100 Subject: [PATCH 3/4] remove deprecation of iteritems --- doc/source/reference/frame.rst | 2 +- doc/source/reference/series.rst | 1 + doc/source/whatsnew/v0.25.0.rst | 1 - pandas/core/frame.py | 5 +++-- pandas/core/series.py | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/doc/source/reference/frame.rst b/doc/source/reference/frame.rst index f99e7ce928237..c0b58fd2d99f5 100644 --- a/doc/source/reference/frame.rst +++ b/doc/source/reference/frame.rst @@ -67,8 +67,8 @@ Indexing, iteration DataFrame.insert DataFrame.__iter__ DataFrame.items + DataFrame.iteritems DataFrame.keys - DataFrame.items DataFrame.iterrows DataFrame.itertuples DataFrame.lookup diff --git a/doc/source/reference/series.rst b/doc/source/reference/series.rst index b3bdc0b193f70..8d2a764c33a43 100644 --- a/doc/source/reference/series.rst +++ b/doc/source/reference/series.rst @@ -77,6 +77,7 @@ Indexing, iteration Series.iloc Series.__iter__ Series.items + Series.iteritems Series.keys Series.pop Series.item diff --git a/doc/source/whatsnew/v0.25.0.rst b/doc/source/whatsnew/v0.25.0.rst index 3eaf409286e2d..a8360d8aeb037 100644 --- a/doc/source/whatsnew/v0.25.0.rst +++ b/doc/source/whatsnew/v0.25.0.rst @@ -886,7 +886,6 @@ Other deprecations - :meth:`Index.item` and :meth:`Series.item` is deprecated. (:issue:`18262`) - The default value ``ordered=None`` in :class:`~pandas.api.types.CategoricalDtype` has been deprecated in favor of ``ordered=False``. When converting between categorical types ``ordered=True`` must be explicitly passed in order to be preserved. (:issue:`26336`) - :meth:`Index.contains` is deprecated. Use ``key in index`` (``__contains__``) instead (:issue:`17753`). -- ``DataFrame.iteritems`` and ``Series.iteritems`` have been deprecated. :attr:`DataFrame.items` and :attr:`Series.items` provide the exact same functionality and should be used instead (:issue:`26114`). - :meth:`DataFrame.get_dtype_counts` is deprecated. (:issue:`18262`) - :meth:`Categorical.ravel` will return a :class:`Categorical` instead of a ``np.ndarray`` (:issue:`27199`) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 14d5c5767a601..b56754c81c93d 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -826,9 +826,10 @@ def items(self): for i, k in enumerate(self.columns): yield k, self._ixs(i, axis=1) - @Appender(items.__doc) + @Appender(items.__doc__) def iteritems(self): - return self.items() + for key, value in self.items(): + yield key, value def iterrows(self): """ diff --git a/pandas/core/series.py b/pandas/core/series.py index ec898ed2b6f72..a4f1f1d2a6296 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -1720,7 +1720,7 @@ def items(self): """ return zip(iter(self.index), iter(self)) - @Appender(generic._shared_docs["iteritems"] % _shared_doc_kwargs) + @Appender(items.__doc__) def iteritems(self): return self.items() From 71c9acab2e86a0be71f6ba96e5c5d7b82a61f360 Mon Sep 17 00:00:00 2001 From: tp Date: Wed, 10 Jul 2019 19:34:03 +0100 Subject: [PATCH 4/4] Change iteritems doc string --- pandas/core/frame.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index b56754c81c93d..55a9eb6a0810a 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -771,15 +771,15 @@ def style(self): return Styler(self) - def items(self): - r""" + _shared_docs[ + "items" + ] = r""" Iterator over (column name, Series) pairs. Iterates over the DataFrame columns, returning a tuple with the column name and the content as a Series. - Yields - ------ + %s label : object The column names for the DataFrame being iterated over. content : Series @@ -819,6 +819,9 @@ def items(self): koala 80000 Name: population, dtype: int64 """ + + @Appender(_shared_docs["items"] % "Yields\n ------") + def items(self): if self.columns.is_unique and hasattr(self, "_item_cache"): for k in self.columns: yield k, self._get_item_cache(k) @@ -826,10 +829,9 @@ def items(self): for i, k in enumerate(self.columns): yield k, self._ixs(i, axis=1) - @Appender(items.__doc__) + @Appender(_shared_docs["items"] % "Returns\n -------") def iteritems(self): - for key, value in self.items(): - yield key, value + return self.items() def iterrows(self): """