Skip to content

Commit db96085

Browse files
committed
Merge pull request #2 from pydata/master
Update from original
2 parents b144cc1 + 676cb95 commit db96085

25 files changed

+517
-124
lines changed

doc/source/groupby.rst

+4-4
Original file line numberDiff line numberDiff line change
@@ -784,11 +784,11 @@ will be (silently) dropped. Thus, this does not pose any problems:
784784
785785
df.groupby('A').std()
786786
787-
NA group handling
788-
~~~~~~~~~~~~~~~~~
787+
NA and NaT group handling
788+
~~~~~~~~~~~~~~~~~~~~~~~~~
789789

790-
If there are any NaN values in the grouping key, these will be automatically
791-
excluded. So there will never be an "NA group". This was not the case in older
790+
If there are any NaN or NaT values in the grouping key, these will be automatically
791+
excluded. So there will never be an "NA group" or "NaT group". This was not the case in older
792792
versions of pandas, but users were generally discarding the NA group anyway
793793
(and supporting it was an implementation headache).
794794

doc/source/whatsnew.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ What's New
1818

1919
These are new features and improvements of note in each release.
2020

21-
.. include:: whatsnew/v0.17.0.txt
21+
.. include:: whatsnew/v0.16.2.txt
2222

2323
.. include:: whatsnew/v0.16.1.txt
2424

doc/source/whatsnew/v0.16.2.txt

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
.. _whatsnew_0162:
2+
3+
v0.16.2 (June 12, 2015)
4+
-----------------------
5+
6+
This is a minor bug-fix release from 0.16.1 and includes a a large number of
7+
bug fixes along several new features, enhancements, and performance improvements.
8+
We recommend that all users upgrade to this version.
9+
10+
Highlights include:
11+
12+
Check the :ref:`API Changes <whatsnew_0162.api>` before updating.
13+
14+
.. contents:: What's new in v0.16.2
15+
:local:
16+
:backlinks: none
17+
18+
.. _whatsnew_0162.enhancements:
19+
20+
New features
21+
~~~~~~~~~~~~
22+
23+
.. _whatsnew_0162.enhancements.other:
24+
25+
Other enhancements
26+
^^^^^^^^^^^^^^^^^^
27+
28+
.. _whatsnew_0162.api:
29+
30+
Backwards incompatible API changes
31+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
32+
33+
.. _whatsnew_0162.api_breaking:
34+
35+
.. _whatsnew_0162.api_breaking.other:
36+
37+
Other API Changes
38+
^^^^^^^^^^^^^^^^^
39+
40+
- ``Holiday`` now raises ``NotImplementedError`` if both ``offset`` and ``observance`` are used in constructor. (:issue:`102171`)
41+
42+
.. _whatsnew_0162.performance:
43+
44+
Performance Improvements
45+
~~~~~~~~~~~~~~~~~~~~~~~~
46+
47+
- Improved ``Series.resample`` performance with dtype=datetime64[ns] (:issue:`7754`)
48+
49+
.. _whatsnew_0162.bug_fixes:
50+
51+
Bug Fixes
52+
~~~~~~~~~
53+
54+
- Bug where read_hdf store.select modifies the passed columns list when
55+
multi-indexed (:issue:`7212`)
56+
- Bug in ``Categorical`` repr with ``display.width`` of ``None`` in Python 3 (:issue:`10087`)
57+
58+
59+
- Bug in ``mean()`` where integer dtypes can overflow (:issue:`10172`)
60+
- Bug where Panel.from_dict does not set dtype when specified (:issue:`10058`)
61+
- Bug in ``Index.union`` raises ``AttributeError`` when passing array-likes. (:issue:`10149`)
62+
- Bug in ``Timestamp``'s' ``microsecond``, ``quarter``, ``dayofyear``, ``week`` and ``daysinmonth`` properties return ``np.int`` type, not built-in ``int``. (:issue:`10050`)
63+
- Bug in ``NaT`` raises ``AttributeError`` when accessing to ``daysinmonth``, ``dayofweek`` properties. (:issue:`10096`)
64+
65+
66+
- Bug in getting timezone data with ``dateutil`` on various platforms ( :issue:`9059`, :issue:`8639`, :issue:`9663`, :issue:`10121`)
67+
- Bug in display datetimes with mixed frequencies uniformly; display 'ms' datetimes to the proper precision. (:issue:`10170`)
68+
69+
- Bung in ``Series`` arithmetic methods may incorrectly hold names (:issue:`10068`)
70+
71+
- Bug in ``DatetimeIndex`` and ``TimedeltaIndex`` names are lost after timedelta arithmetics ( :issue:`9926`)
72+
73+
74+
- Bug in `Series.plot(label="LABEL")` not correctly setting the label (:issue:`10119`)
75+
76+
- Bug in `plot` not defaulting to matplotlib `axes.grid` setting (:issue:`9792`)
77+
78+
- Bug in ``Series.align`` resets ``name`` when ``fill_value`` is specified (:issue:`10067`)
79+
- Bug in ``SparseSeries.abs`` resets ``name`` (:issue:`10241`)
80+
81+
82+
- Bug in GroupBy.get_group raises ValueError when group key contains NaT (:issue:`6992`)
83+
84+
85+
- Bug where infer_freq infers timerule (WOM-5XXX) unsupported by to_offset (:issue:`9425`)

doc/source/whatsnew/v0.17.0.txt

+2-24
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
.. _whatsnew_0170:
22

3-
v0.17.0 (July ??, 2015)
3+
v0.17.0 (July 31, 2015)
44
-----------------------
55

6-
This is a major release from 0.16.1 and includes a small number of API changes, several new features,
6+
This is a major release from 0.16.2 and includes a small number of API changes, several new features,
77
enhancements, and performance improvements along with a large number of bug fixes. We recommend that all
88
users upgrade to this version.
99

@@ -53,29 +53,7 @@ Removal of prior version deprecations/changes
5353
Performance Improvements
5454
~~~~~~~~~~~~~~~~~~~~~~~~
5555

56-
- Improved ``Series.resample`` performance with dtype=datetime64[ns] (:issue:`7754`)
57-
5856
.. _whatsnew_0170.bug_fixes:
5957

6058
Bug Fixes
6159
~~~~~~~~~
62-
63-
- Bug where read_hdf store.select modifies the passed columns list when
64-
multi-indexed (:issue:`7212`)
65-
- Bug in ``Categorical`` repr with ``display.width`` of ``None`` in Python 3 (:issue:`10087`)
66-
67-
68-
- Bug where Panel.from_dict does not set dtype when specified (:issue:`10058`)
69-
- Bug in ``Timestamp``'s' ``microsecond``, ``quarter``, ``dayofyear``, ``week`` and ``daysinmonth`` properties return ``np.int`` type, not built-in ``int``. (:issue:`10050`)
70-
- Bug in ``NaT`` raises ``AttributeError`` when accessing to ``daysinmonth``, ``dayofweek`` properties. (:issue:`10096`)
71-
72-
- Bug in getting timezone data with ``dateutil`` on various platforms ( :issue:`9059`, :issue:`8639`, :issue:`9663`, :issue:`10121`)
73-
- Bug in display datetimes with mixed frequencies uniformly; display 'ms' datetimes to the proper precision. (:issue:`10170`)
74-
75-
76-
- Bug in ``DatetimeIndex`` and ``TimedeltaIndex`` names are lost after timedelta arithmetics ( :issue:`9926`)
77-
78-
- Bug in `Series.plot(label="LABEL")` not correctly setting the label (:issue:`10119`)
79-
- Bug in `plot` not defaulting to matplotlib `axes.grid` setting (:issue:`9792`)
80-
81-

pandas/core/generic.py

+8-13
Original file line numberDiff line numberDiff line change
@@ -3365,11 +3365,10 @@ def _align_series(self, other, join='outer', axis=None, level=None,
33653365
level=level,
33663366
return_indexers=True)
33673367

3368-
left_result = self._reindex_indexer(join_index, lidx, copy)
3369-
right_result = other._reindex_indexer(join_index, ridx, copy)
3368+
left = self._reindex_indexer(join_index, lidx, copy)
3369+
right = other._reindex_indexer(join_index, ridx, copy)
33703370

33713371
else:
3372-
33733372
# one has > 1 ndim
33743373
fdata = self._data
33753374
if axis == 0:
@@ -3399,23 +3398,19 @@ def _align_series(self, other, join='outer', axis=None, level=None,
33993398
if copy and fdata is self._data:
34003399
fdata = fdata.copy()
34013400

3402-
left_result = DataFrame(fdata)
3401+
left = DataFrame(fdata)
34033402

34043403
if ridx is None:
3405-
right_result = other
3404+
right = other
34063405
else:
3407-
right_result = other.reindex(join_index, level=level)
3406+
right = other.reindex(join_index, level=level)
34083407

34093408
# fill
34103409
fill_na = notnull(fill_value) or (method is not None)
34113410
if fill_na:
3412-
return (left_result.fillna(fill_value, method=method, limit=limit,
3413-
axis=fill_axis),
3414-
right_result.fillna(fill_value, method=method,
3415-
limit=limit))
3416-
else:
3417-
return (left_result.__finalize__(self),
3418-
right_result.__finalize__(other))
3411+
left = left.fillna(fill_value, method=method, limit=limit, axis=fill_axis)
3412+
right = right.fillna(fill_value, method=method, limit=limit)
3413+
return (left.__finalize__(self), right.__finalize__(other))
34193414

34203415
_shared_docs['where'] = ("""
34213416
Return an object of same shape as self and whose corresponding

pandas/core/groupby.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,11 @@ def convert(key, s):
426426
return Timestamp(key).asm8
427427
return key
428428

429-
sample = next(iter(self.indices))
429+
if len(self.indices) > 0:
430+
sample = next(iter(self.indices))
431+
else:
432+
sample = None # Dummy sample
433+
430434
if isinstance(sample, tuple):
431435
if not isinstance(name, tuple):
432436
msg = ("must supply a tuple to get_group with multiple"

pandas/core/index.py

+42-42
Original file line numberDiff line numberDiff line change
@@ -580,8 +580,18 @@ def to_datetime(self, dayfirst=False):
580580
return DatetimeIndex(self.values)
581581

582582
def _assert_can_do_setop(self, other):
583+
if not com.is_list_like(other):
584+
raise TypeError('Input must be Index or array-like')
583585
return True
584586

587+
def _convert_can_do_setop(self, other):
588+
if not isinstance(other, Index):
589+
other = Index(other, name=self.name)
590+
result_name = self.name
591+
else:
592+
result_name = self.name if self.name == other.name else None
593+
return other, result_name
594+
585595
@property
586596
def nlevels(self):
587597
return 1
@@ -1364,16 +1374,14 @@ def union(self, other):
13641374
-------
13651375
union : Index
13661376
"""
1367-
if not hasattr(other, '__iter__'):
1368-
raise TypeError('Input must be iterable.')
1377+
self._assert_can_do_setop(other)
1378+
other = _ensure_index(other)
13691379

13701380
if len(other) == 0 or self.equals(other):
13711381
return self
13721382

13731383
if len(self) == 0:
1374-
return _ensure_index(other)
1375-
1376-
self._assert_can_do_setop(other)
1384+
return other
13771385

13781386
if not is_dtype_equal(self.dtype,other.dtype):
13791387
this = self.astype('O')
@@ -1439,11 +1447,7 @@ def intersection(self, other):
14391447
-------
14401448
intersection : Index
14411449
"""
1442-
if not hasattr(other, '__iter__'):
1443-
raise TypeError('Input must be iterable!')
1444-
14451450
self._assert_can_do_setop(other)
1446-
14471451
other = _ensure_index(other)
14481452

14491453
if self.equals(other):
@@ -1492,18 +1496,12 @@ def difference(self, other):
14921496
14931497
>>> index.difference(index2)
14941498
"""
1495-
1496-
if not hasattr(other, '__iter__'):
1497-
raise TypeError('Input must be iterable!')
1499+
self._assert_can_do_setop(other)
14981500

14991501
if self.equals(other):
15001502
return Index([], name=self.name)
15011503

1502-
if not isinstance(other, Index):
1503-
other = np.asarray(other)
1504-
result_name = self.name
1505-
else:
1506-
result_name = self.name if self.name == other.name else None
1504+
other, result_name = self._convert_can_do_setop(other)
15071505

15081506
theDiff = sorted(set(self) - set(other))
15091507
return Index(theDiff, name=result_name)
@@ -1517,7 +1515,7 @@ def sym_diff(self, other, result_name=None):
15171515
Parameters
15181516
----------
15191517
1520-
other : array-like
1518+
other : Index or array-like
15211519
result_name : str
15221520
15231521
Returns
@@ -1545,13 +1543,10 @@ def sym_diff(self, other, result_name=None):
15451543
>>> idx1 ^ idx2
15461544
Int64Index([1, 5], dtype='int64')
15471545
"""
1548-
if not hasattr(other, '__iter__'):
1549-
raise TypeError('Input must be iterable!')
1550-
1551-
if not isinstance(other, Index):
1552-
other = Index(other)
1553-
result_name = result_name or self.name
1554-
1546+
self._assert_can_do_setop(other)
1547+
other, result_name_update = self._convert_can_do_setop(other)
1548+
if result_name is None:
1549+
result_name = result_name_update
15551550
the_diff = sorted(set((self.difference(other)).union(other.difference(self))))
15561551
return Index(the_diff, name=result_name)
15571552

@@ -5460,12 +5455,11 @@ def union(self, other):
54605455
>>> index.union(index2)
54615456
"""
54625457
self._assert_can_do_setop(other)
5458+
other, result_names = self._convert_can_do_setop(other)
54635459

54645460
if len(other) == 0 or self.equals(other):
54655461
return self
54665462

5467-
result_names = self.names if self.names == other.names else None
5468-
54695463
uniq_tuples = lib.fast_unique_multiple([self.values, other.values])
54705464
return MultiIndex.from_arrays(lzip(*uniq_tuples), sortorder=0,
54715465
names=result_names)
@@ -5483,12 +5477,11 @@ def intersection(self, other):
54835477
Index
54845478
"""
54855479
self._assert_can_do_setop(other)
5480+
other, result_names = self._convert_can_do_setop(other)
54865481

54875482
if self.equals(other):
54885483
return self
54895484

5490-
result_names = self.names if self.names == other.names else None
5491-
54925485
self_tuples = self.values
54935486
other_tuples = other.values
54945487
uniq_tuples = sorted(set(self_tuples) & set(other_tuples))
@@ -5509,18 +5502,10 @@ def difference(self, other):
55095502
diff : MultiIndex
55105503
"""
55115504
self._assert_can_do_setop(other)
5505+
other, result_names = self._convert_can_do_setop(other)
55125506

5513-
if not isinstance(other, MultiIndex):
5514-
if len(other) == 0:
5507+
if len(other) == 0:
55155508
return self
5516-
try:
5517-
other = MultiIndex.from_tuples(other)
5518-
except:
5519-
raise TypeError('other must be a MultiIndex or a list of'
5520-
' tuples')
5521-
result_names = self.names
5522-
else:
5523-
result_names = self.names if self.names == other.names else None
55245509

55255510
if self.equals(other):
55265511
return MultiIndex(levels=[[]] * self.nlevels,
@@ -5537,15 +5522,30 @@ def difference(self, other):
55375522
return MultiIndex.from_tuples(difference, sortorder=0,
55385523
names=result_names)
55395524

5540-
def _assert_can_do_setop(self, other):
5541-
pass
5542-
55435525
def astype(self, dtype):
55445526
if not is_object_dtype(np.dtype(dtype)):
55455527
raise TypeError('Setting %s dtype to anything other than object '
55465528
'is not supported' % self.__class__)
55475529
return self._shallow_copy()
55485530

5531+
def _convert_can_do_setop(self, other):
5532+
result_names = self.names
5533+
5534+
if not hasattr(other, 'names'):
5535+
if len(other) == 0:
5536+
other = MultiIndex(levels=[[]] * self.nlevels,
5537+
labels=[[]] * self.nlevels,
5538+
verify_integrity=False)
5539+
else:
5540+
msg = 'other must be a MultiIndex or a list of tuples'
5541+
try:
5542+
other = MultiIndex.from_tuples(other)
5543+
except:
5544+
raise TypeError(msg)
5545+
else:
5546+
result_names = self.names if self.names == other.names else None
5547+
return other, result_names
5548+
55495549
def insert(self, loc, item):
55505550
"""
55515551
Make new MultiIndex inserting new item at location

0 commit comments

Comments
 (0)