Skip to content

Commit a33a55b

Browse files
committed
Merge branch 'master' of https://github.com/pandas-dev/pandas into collect
2 parents 7bf6b6f + 6efc237 commit a33a55b

34 files changed

+434
-384
lines changed

ci/run_tests.sh

+3-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ echo $PYTEST_CMD
3737
sh -c "$PYTEST_CMD"
3838

3939
if [[ "$COVERAGE" && $? == 0 && "$TRAVIS_BRANCH" == "master" ]]; then
40+
SHA=`git rev-parse HEAD`
4041
echo "uploading coverage"
41-
echo "bash <(curl -s https://codecov.io/bash) -Z -c -F $TYPE -f $COVERAGE_FNAME"
42-
bash <(curl -s https://codecov.io/bash) -Z -c -F $TYPE -f $COVERAGE_FNAME
42+
echo "bash <(curl -s https://codecov.io/bash) -Z -c -F $TYPE -f $COVERAGE_FNAME -C $SHA"
43+
bash <(curl -s https://codecov.io/bash) -Z -c -F $TYPE -f $COVERAGE_FNAME -C `git rev-parse HEAD`
4344
fi

doc/source/whatsnew/v1.0.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,7 @@ Datetimelike
712712
- Bug in :func:`pandas.to_datetime` when called with ``None`` raising ``TypeError`` instead of returning ``NaT`` (:issue:`30011`)
713713
- Bug in :func:`pandas.to_datetime` failing for `deques` when using ``cache=True`` (the default) (:issue:`29403`)
714714
- Bug in :meth:`Series.item` with ``datetime64`` or ``timedelta64`` dtype, :meth:`DatetimeIndex.item`, and :meth:`TimedeltaIndex.item` returning an integer instead of a :class:`Timestamp` or :class:`Timedelta` (:issue:`30175`)
715-
-
715+
- Bug in :class:`DatetimeIndex` addition when adding a non-optimized :class:`DateOffset` incorrectly dropping timezone information (:issue:`30336`)
716716

717717
Timedelta
718718
^^^^^^^^^

pandas/_libs/parsers.pyx

+20-1
Original file line numberDiff line numberDiff line change
@@ -1367,7 +1367,26 @@ def _ensure_encoded(list lst):
13671367
# common NA values
13681368
# no longer excluding inf representations
13691369
# '1.#INF','-1.#INF', '1.#INF000000',
1370-
_NA_VALUES = _ensure_encoded(list(icom._NA_VALUES))
1370+
STR_NA_VALUES = {
1371+
"-1.#IND",
1372+
"1.#QNAN",
1373+
"1.#IND",
1374+
"-1.#QNAN",
1375+
"#N/A N/A",
1376+
"#N/A",
1377+
"N/A",
1378+
"n/a",
1379+
"NA",
1380+
"#NA",
1381+
"NULL",
1382+
"null",
1383+
"NaN",
1384+
"-NaN",
1385+
"nan",
1386+
"-nan",
1387+
"",
1388+
}
1389+
_NA_VALUES = _ensure_encoded(list(STR_NA_VALUES))
13711390

13721391

13731392
def _maybe_upcast(arr):

pandas/core/arrays/datetimes.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -794,16 +794,17 @@ def _add_offset(self, offset):
794794
values = self.tz_localize(None)
795795
else:
796796
values = self
797-
result = offset.apply_index(values)
798-
if self.tz is not None:
799-
result = result.tz_localize(self.tz)
797+
result = offset.apply_index(values).tz_localize(self.tz)
800798

801799
except NotImplementedError:
802800
warnings.warn(
803801
"Non-vectorized DateOffset being applied to Series or DatetimeIndex",
804802
PerformanceWarning,
805803
)
806804
result = self.astype("O") + offset
805+
if len(self) == 0:
806+
# _from_sequence won't be able to infer self.tz
807+
return type(self)._from_sequence(result).tz_localize(self.tz)
807808

808809
return type(self)._from_sequence(result, freq="infer")
809810

pandas/core/indexing.py

+11-25
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ def _has_valid_tuple(self, key: Tuple):
232232
except ValueError:
233233
raise ValueError(
234234
"Location based indexing can only have "
235-
"[{types}] types".format(types=self._valid_types)
235+
f"[{self._valid_types}] types"
236236
)
237237

238238
def _is_nested_tuple_indexer(self, tup: Tuple) -> bool:
@@ -286,7 +286,7 @@ def _has_valid_positional_setitem_indexer(self, indexer) -> bool:
286286
bool
287287
"""
288288
if isinstance(indexer, dict):
289-
raise IndexError("{0} cannot enlarge its target object".format(self.name))
289+
raise IndexError(f"{self.name} cannot enlarge its target object")
290290
else:
291291
if not isinstance(indexer, tuple):
292292
indexer = _tuplify(self.ndim, indexer)
@@ -300,13 +300,10 @@ def _has_valid_positional_setitem_indexer(self, indexer) -> bool:
300300
elif is_integer(i):
301301
if i >= len(ax):
302302
raise IndexError(
303-
"{name} cannot enlarge its target "
304-
"object".format(name=self.name)
303+
f"{self.name} cannot enlarge its target object"
305304
)
306305
elif isinstance(i, dict):
307-
raise IndexError(
308-
"{name} cannot enlarge its target object".format(name=self.name)
309-
)
306+
raise IndexError(f"{self.name} cannot enlarge its target object")
310307

311308
return True
312309

@@ -1166,17 +1163,14 @@ def _validate_read_indexer(
11661163

11671164
if missing:
11681165
if missing == len(indexer):
1169-
raise KeyError(
1170-
"None of [{key}] are in the [{axis}]".format(
1171-
key=key, axis=self.obj._get_axis_name(axis)
1172-
)
1173-
)
1166+
axis_name = self.obj._get_axis_name(axis)
1167+
raise KeyError(f"None of [{key}] are in the [{axis_name}]")
11741168

11751169
# We (temporarily) allow for some missing keys with .loc, except in
11761170
# some cases (e.g. setting) in which "raise_missing" will be False
11771171
if not (self.name == "loc" and not raise_missing):
11781172
not_found = list(set(key) - set(ax))
1179-
raise KeyError("{} not in index".format(not_found))
1173+
raise KeyError(f"{not_found} not in index")
11801174

11811175
# we skip the warning on Categorical/Interval
11821176
# as this check is actually done (check for
@@ -1905,18 +1899,13 @@ def _validate_key(self, key, axis: int):
19051899

19061900
# check that the key has a numeric dtype
19071901
if not is_numeric_dtype(arr.dtype):
1908-
raise IndexError(
1909-
".iloc requires numeric indexers, got {arr}".format(arr=arr)
1910-
)
1902+
raise IndexError(f".iloc requires numeric indexers, got {arr}")
19111903

19121904
# check that the key does not exceed the maximum size of the index
19131905
if len(arr) and (arr.max() >= len_axis or arr.min() < -len_axis):
19141906
raise IndexError("positional indexers are out-of-bounds")
19151907
else:
1916-
raise ValueError(
1917-
"Can only index by location with "
1918-
"a [{types}]".format(types=self._valid_types)
1919-
)
1908+
raise ValueError(f"Can only index by location with a [{self._valid_types}]")
19201909

19211910
def _has_valid_setitem_indexer(self, indexer):
19221911
self._has_valid_positional_setitem_indexer(indexer)
@@ -2063,10 +2052,7 @@ def _convert_to_indexer(self, obj, axis: int, raise_missing: bool = False):
20632052
self._validate_key(obj, axis)
20642053
return obj
20652054
except ValueError:
2066-
raise ValueError(
2067-
"Can only index by location with "
2068-
"a [{types}]".format(types=self._valid_types)
2069-
)
2055+
raise ValueError(f"Can only index by location with a [{self._valid_types}]")
20702056

20712057

20722058
class _ScalarAccessIndexer(_NDFrameIndexerBase):
@@ -2327,7 +2313,7 @@ def check_bool_indexer(index: Index, key) -> np.ndarray:
23272313
# GH26658
23282314
if len(result) != len(index):
23292315
raise IndexError(
2330-
"Item wrong length {} instead of {}.".format(len(result), len(index))
2316+
f"Item wrong length {len(result)} instead of {len(index)}."
23312317
)
23322318

23332319
return result

pandas/core/internals/blocks.py

+26-38
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ def __init__(self, values, placement, ndim=None):
115115

116116
if self._validate_ndim and self.ndim and len(self.mgr_locs) != len(self.values):
117117
raise ValueError(
118-
"Wrong number of items passed {val}, placement implies "
119-
"{mgr}".format(val=len(self.values), mgr=len(self.mgr_locs))
118+
f"Wrong number of items passed {len(self.values)}, "
119+
f"placement implies {len(self.mgr_locs)}"
120120
)
121121

122122
def _check_ndim(self, values, ndim):
@@ -144,9 +144,10 @@ def _check_ndim(self, values, ndim):
144144
ndim = values.ndim
145145

146146
if self._validate_ndim and values.ndim != ndim:
147-
msg = "Wrong number of dimensions. values.ndim != ndim [{} != {}]"
148-
raise ValueError(msg.format(values.ndim, ndim))
149-
147+
raise ValueError(
148+
"Wrong number of dimensions. "
149+
f"values.ndim != ndim [{values.ndim} != {ndim}]"
150+
)
150151
return ndim
151152

152153
@property
@@ -184,7 +185,7 @@ def is_categorical_astype(self, dtype):
184185
if dtype is Categorical or dtype is CategoricalDtype:
185186
# this is a pd.Categorical, but is not
186187
# a valid type for astypeing
187-
raise TypeError("invalid type {0} for astype".format(dtype))
188+
raise TypeError(f"invalid type {dtype} for astype")
188189

189190
elif is_categorical_dtype(dtype):
190191
return True
@@ -264,18 +265,14 @@ def __repr__(self) -> str:
264265
name = type(self).__name__
265266
if self._is_single_block:
266267

267-
result = "{name}: {len} dtype: {dtype}".format(
268-
name=name, len=len(self), dtype=self.dtype
269-
)
268+
result = f"{name}: {len(self)} dtype: {self.dtype}"
270269

271270
else:
272271

273272
shape = " x ".join(pprint_thing(s) for s in self.shape)
274-
result = "{name}: {index}, {shape}, dtype: {dtype}".format(
275-
name=name,
276-
index=pprint_thing(self.mgr_locs.indexer),
277-
shape=shape,
278-
dtype=self.dtype,
273+
result = (
274+
f"{name}: {pprint_thing(self.mgr_locs.indexer)}, "
275+
f"{shape}, dtype: {self.dtype}"
279276
)
280277

281278
return result
@@ -329,7 +326,7 @@ def ftype(self):
329326
dtype = self.dtype.subtype
330327
else:
331328
dtype = self.dtype
332-
return "{dtype}:{ftype}".format(dtype=dtype, ftype=self._ftype)
329+
return f"{dtype}:{self._ftype}"
333330

334331
def merge(self, other):
335332
return _merge_blocks([self, other])
@@ -544,15 +541,15 @@ def astype(self, dtype, copy: bool = False, errors: str = "raise"):
544541

545542
if errors not in errors_legal_values:
546543
invalid_arg = (
547-
"Expected value of kwarg 'errors' to be one of {}. "
548-
"Supplied value is '{}'".format(list(errors_legal_values), errors)
544+
"Expected value of kwarg 'errors' to be one of "
545+
f"{list(errors_legal_values)}. Supplied value is '{errors}'"
549546
)
550547
raise ValueError(invalid_arg)
551548

552549
if inspect.isclass(dtype) and issubclass(dtype, ExtensionDtype):
553550
msg = (
554-
"Expected an instance of {}, but got the class instead. "
555-
"Try instantiating 'dtype'.".format(dtype.__name__)
551+
f"Expected an instance of {dtype.__name__}, "
552+
"but got the class instead. Try instantiating 'dtype'."
556553
)
557554
raise TypeError(msg)
558555

@@ -613,15 +610,9 @@ def astype(self, dtype, copy: bool = False, errors: str = "raise"):
613610
if newb.is_numeric and self.is_numeric:
614611
if newb.shape != self.shape:
615612
raise TypeError(
616-
"cannot set astype for copy = [{copy}] for dtype "
617-
"({dtype} [{shape}]) to different shape "
618-
"({newb_dtype} [{newb_shape}])".format(
619-
copy=copy,
620-
dtype=self.dtype.name,
621-
shape=self.shape,
622-
newb_dtype=newb.dtype.name,
623-
newb_shape=newb.shape,
624-
)
613+
f"cannot set astype for copy = [{copy}] for dtype "
614+
f"({self.dtype.name} [{self.shape}]) to different shape "
615+
f"({newb.dtype.name} [{newb.shape}])"
625616
)
626617
return newb
627618

@@ -658,7 +649,7 @@ def to_native_types(self, slicer=None, na_rep="nan", quoting=None, **kwargs):
658649

659650
if not self.is_object and not quoting:
660651
itemsize = writers.word_len(na_rep)
661-
values = values.astype("<U{size}".format(size=itemsize))
652+
values = values.astype(f"<U{itemsize}")
662653
else:
663654
values = np.array(values, dtype="object")
664655

@@ -1045,8 +1036,7 @@ def coerce_to_target_dtype(self, other):
10451036
return self.astype(object)
10461037

10471038
raise AssertionError(
1048-
"possible recursion in "
1049-
"coerce_to_target_dtype: {} {}".format(self, other)
1039+
f"possible recursion in coerce_to_target_dtype: {self} {other}"
10501040
)
10511041

10521042
elif self.is_timedelta or is_timedelta64_dtype(dtype):
@@ -1056,8 +1046,7 @@ def coerce_to_target_dtype(self, other):
10561046
return self.astype(object)
10571047

10581048
raise AssertionError(
1059-
"possible recursion in "
1060-
"coerce_to_target_dtype: {} {}".format(self, other)
1049+
f"possible recursion in coerce_to_target_dtype: {self} {other}"
10611050
)
10621051

10631052
try:
@@ -1202,8 +1191,7 @@ def _interpolate(
12021191
if method in ("krogh", "piecewise_polynomial", "pchip"):
12031192
if not index.is_monotonic:
12041193
raise ValueError(
1205-
"{0} interpolation requires that the "
1206-
"index be monotonic.".format(method)
1194+
f"{method} interpolation requires that the index be monotonic."
12071195
)
12081196
# process 1-d slices in the axis direction
12091197

@@ -1585,15 +1573,15 @@ def iget(self, col):
15851573
if self.ndim == 2 and isinstance(col, tuple):
15861574
col, loc = col
15871575
if not com.is_null_slice(col) and col != 0:
1588-
raise IndexError("{0} only contains one item".format(self))
1576+
raise IndexError(f"{self} only contains one item")
15891577
elif isinstance(col, slice):
15901578
if col != slice(None):
15911579
raise NotImplementedError(col)
15921580
return self.values[[loc]]
15931581
return self.values[loc]
15941582
else:
15951583
if col != 0:
1596-
raise IndexError("{0} only contains one item".format(self))
1584+
raise IndexError(f"{self} only contains one item")
15971585
return self.values
15981586

15991587
def should_store(self, value):
@@ -2312,7 +2300,7 @@ def _slice(self, slicer):
23122300
if isinstance(slicer, tuple):
23132301
col, loc = slicer
23142302
if not com.is_null_slice(col) and col != 0:
2315-
raise IndexError("{0} only contains one item".format(self))
2303+
raise IndexError(f"{self} only contains one item")
23162304
return self.values[loc]
23172305
return self.values[slicer]
23182306

pandas/core/internals/construction.py

+6-7
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,7 @@ def init_ndarray(values, index, columns, dtype=None, copy=False):
167167
except Exception as orig:
168168
# e.g. ValueError when trying to cast object dtype to float64
169169
raise ValueError(
170-
"failed to cast to '{dtype}' (Exception "
171-
"was: {orig})".format(dtype=dtype, orig=orig)
170+
f"failed to cast to '{dtype}' (Exception was: {orig})"
172171
) from orig
173172

174173
index, columns = _get_axes(*values.shape, index=index, columns=columns)
@@ -365,8 +364,8 @@ def extract_index(data):
365364
if have_series:
366365
if lengths[0] != len(index):
367366
msg = (
368-
"array length {length} does not match index "
369-
"length {idx_len}".format(length=lengths[0], idx_len=len(index))
367+
f"array length {lengths[0]} does not match index "
368+
f"length {len(index)}"
370369
)
371370
raise ValueError(msg)
372371
else:
@@ -401,7 +400,7 @@ def get_names_from_index(data):
401400
if n is not None:
402401
index[i] = n
403402
else:
404-
index[i] = "Unnamed {count}".format(count=count)
403+
index[i] = f"Unnamed {count}"
405404
count += 1
406405

407406
return index
@@ -571,8 +570,8 @@ def _convert_object_array(content, columns, coerce_float=False, dtype=None):
571570
if len(columns) != len(content): # pragma: no cover
572571
# caller's responsibility to check for this...
573572
raise AssertionError(
574-
"{col:d} columns passed, passed data had "
575-
"{con} columns".format(col=len(columns), con=len(content))
573+
f"{len(columns)} columns passed, passed data had "
574+
f"{len(content)} columns"
576575
)
577576

578577
# provide soft conversion of object dtypes

0 commit comments

Comments
 (0)