Skip to content

Commit 17827de

Browse files
committed
Merge branch 'master' into fix-25691
* master: Fixturize tests/frame/test_operators.py (pandas-dev#25641) Update ValueError message in corr (pandas-dev#25729) # Conflicts: # doc/source/whatsnew/v0.25.0.rst
2 parents 2f00c7f + 998e1de commit 17827de

File tree

6 files changed

+75
-74
lines changed

6 files changed

+75
-74
lines changed

doc/source/whatsnew/v0.25.0.rst

+2-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ Bug Fixes
124124
~~~~~~~~~
125125
- Bug in :func:`to_datetime` which would raise an (incorrect) ``ValueError`` when called with a date far into the future and the ``format`` argument specified instead of raising ``OutOfBoundsDatetime`` (:issue:`23830`)
126126
- Bug in an error message in :meth:`DataFrame.plot`. Improved the error message if non-numerics are passed to :meth:`DataFrame.plot` (:issue:`25481`)
127-
- Segmentation fault when construct :class:`DataFrame` from non-empty tuples (:issue:`25691`)
127+
- Bug in error messages in :meth:`DataFrame.corr` and :meth:`Series.corr`. Added the possibility of using a callable. (:issue:`25729`)
128128

129129
Categorical
130130
^^^^^^^^^^^
@@ -245,6 +245,7 @@ Reshaping
245245
- Bug in :func:`merge` when merging by index name would sometimes result in an incorrectly numbered index (:issue:`24212`)
246246
- :func:`to_records` now accepts dtypes to its `column_dtypes` parameter (:issue:`24895`)
247247
- Bug in :func:`concat` where order of ``OrderedDict`` (and ``dict`` in Python 3.6+) is not respected, when passed in as ``objs`` argument (:issue:`21510`)
248+
- Segmentation fault when construct :class:`DataFrame` from non-empty tuples (:issue:`25691`)
248249

249250

250251
Sparse

pandas/core/frame.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -7088,8 +7088,8 @@ def corr(self, method='pearson', min_periods=1):
70887088
correl[j, i] = c
70897089
else:
70907090
raise ValueError("method must be either 'pearson', "
7091-
"'spearman', or 'kendall', '{method}' "
7092-
"was supplied".format(method=method))
7091+
"'spearman', 'kendall', or a callable, "
7092+
"'{method}' was supplied".format(method=method))
70937093

70947094
return self._constructor(correl, index=idx, columns=cols)
70957095

pandas/core/series.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -2159,8 +2159,8 @@ def corr(self, other, method='pearson', min_periods=None):
21592159
min_periods=min_periods)
21602160

21612161
raise ValueError("method must be either 'pearson', "
2162-
"'spearman', or 'kendall', '{method}' "
2163-
"was supplied".format(method=method))
2162+
"'spearman', 'kendall', or a callable, "
2163+
"'{method}' was supplied".format(method=method))
21642164

21652165
def cov(self, other, min_periods=None):
21662166
"""

pandas/tests/frame/test_analytics.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -332,8 +332,8 @@ def test_corr_cov_independent_index_column(self):
332332
def test_corr_invalid_method(self):
333333
# GH 22298
334334
df = pd.DataFrame(np.random.normal(size=(10, 2)))
335-
msg = ("method must be either 'pearson', 'spearman', "
336-
"or 'kendall'")
335+
msg = ("method must be either 'pearson', "
336+
"'spearman', 'kendall', or a callable, ")
337337
with pytest.raises(ValueError, match=msg):
338338
df.corr(method="____")
339339

pandas/tests/frame/test_operators.py

+65-65
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import pandas as pd
1414
from pandas import DataFrame, MultiIndex, Series, compat
1515
import pandas.core.common as com
16-
from pandas.tests.frame.common import TestData, _check_mixed_float
16+
from pandas.tests.frame.common import _check_mixed_float
1717
import pandas.util.testing as tm
1818
from pandas.util.testing import (
1919
assert_frame_equal, assert_numpy_array_equal, assert_series_equal)
@@ -207,7 +207,7 @@ def test_logical_with_nas(self):
207207
assert_series_equal(result, expected)
208208

209209

210-
class TestDataFrameOperators(TestData):
210+
class TestDataFrameOperators(object):
211211

212212
@pytest.mark.parametrize('op', [operator.add, operator.sub,
213213
operator.mul, operator.truediv])
@@ -238,9 +238,9 @@ def test_operators_none_as_na(self, op):
238238
('__ne__', True)])
239239
# TODO: not sure what's correct here.
240240
@pytest.mark.filterwarnings("ignore:elementwise:FutureWarning")
241-
def test_logical_typeerror_with_non_valid(self, op, res):
241+
def test_logical_typeerror_with_non_valid(self, op, res, float_frame):
242242
# we are comparing floats vs a string
243-
result = getattr(self.frame, op)('foo')
243+
result = getattr(float_frame, op)('foo')
244244
assert bool(result.all().all()) is res
245245

246246
def test_binary_ops_align(self):
@@ -318,16 +318,17 @@ def test_dti_tz_convert_to_utc(self):
318318
exp = DataFrame({'A': [np.nan, 3, np.nan]}, index=base)
319319
assert_frame_equal(df1 + df2, exp)
320320

321-
def test_combineFrame(self):
322-
frame_copy = self.frame.reindex(self.frame.index[::2])
321+
def test_combineFrame(self, float_frame, mixed_float_frame,
322+
mixed_int_frame):
323+
frame_copy = float_frame.reindex(float_frame.index[::2])
323324

324325
del frame_copy['D']
325326
frame_copy['C'][:5] = np.nan
326327

327-
added = self.frame + frame_copy
328+
added = float_frame + frame_copy
328329

329330
indexer = added['A'].dropna().index
330-
exp = (self.frame['A'] * 2).copy()
331+
exp = (float_frame['A'] * 2).copy()
331332

332333
tm.assert_series_equal(added['A'].dropna(), exp.loc[indexer])
333334

@@ -340,95 +341,94 @@ def test_combineFrame(self):
340341

341342
assert np.isnan(added['D']).all()
342343

343-
self_added = self.frame + self.frame
344-
tm.assert_index_equal(self_added.index, self.frame.index)
344+
self_added = float_frame + float_frame
345+
tm.assert_index_equal(self_added.index, float_frame.index)
345346

346-
added_rev = frame_copy + self.frame
347+
added_rev = frame_copy + float_frame
347348
assert np.isnan(added['D']).all()
348349
assert np.isnan(added_rev['D']).all()
349350

350351
# corner cases
351352

352353
# empty
353-
plus_empty = self.frame + self.empty
354+
plus_empty = float_frame + DataFrame()
354355
assert np.isnan(plus_empty.values).all()
355356

356-
empty_plus = self.empty + self.frame
357+
empty_plus = DataFrame() + float_frame
357358
assert np.isnan(empty_plus.values).all()
358359

359-
empty_empty = self.empty + self.empty
360+
empty_empty = DataFrame() + DataFrame()
360361
assert empty_empty.empty
361362

362363
# out of order
363-
reverse = self.frame.reindex(columns=self.frame.columns[::-1])
364+
reverse = float_frame.reindex(columns=float_frame.columns[::-1])
364365

365-
assert_frame_equal(reverse + self.frame, self.frame * 2)
366+
assert_frame_equal(reverse + float_frame, float_frame * 2)
366367

367368
# mix vs float64, upcast
368-
added = self.frame + self.mixed_float
369+
added = float_frame + mixed_float_frame
369370
_check_mixed_float(added, dtype='float64')
370-
added = self.mixed_float + self.frame
371+
added = mixed_float_frame + float_frame
371372
_check_mixed_float(added, dtype='float64')
372373

373374
# mix vs mix
374-
added = self.mixed_float + self.mixed_float2
375-
_check_mixed_float(added, dtype=dict(C=None))
376-
added = self.mixed_float2 + self.mixed_float
375+
added = mixed_float_frame + mixed_float_frame
377376
_check_mixed_float(added, dtype=dict(C=None))
378377

379378
# with int
380-
added = self.frame + self.mixed_int
379+
added = float_frame + mixed_int_frame
381380
_check_mixed_float(added, dtype='float64')
382381

383-
def test_combineSeries(self):
382+
def test_combineSeries(self, float_frame, mixed_float_frame,
383+
mixed_int_frame, datetime_frame):
384384

385385
# Series
386-
series = self.frame.xs(self.frame.index[0])
386+
series = float_frame.xs(float_frame.index[0])
387387

388-
added = self.frame + series
388+
added = float_frame + series
389389

390390
for key, s in compat.iteritems(added):
391-
assert_series_equal(s, self.frame[key] + series[key])
391+
assert_series_equal(s, float_frame[key] + series[key])
392392

393393
larger_series = series.to_dict()
394394
larger_series['E'] = 1
395395
larger_series = Series(larger_series)
396-
larger_added = self.frame + larger_series
396+
larger_added = float_frame + larger_series
397397

398-
for key, s in compat.iteritems(self.frame):
398+
for key, s in compat.iteritems(float_frame):
399399
assert_series_equal(larger_added[key], s + series[key])
400400
assert 'E' in larger_added
401401
assert np.isnan(larger_added['E']).all()
402402

403403
# no upcast needed
404-
added = self.mixed_float + series
404+
added = mixed_float_frame + series
405405
_check_mixed_float(added)
406406

407407
# vs mix (upcast) as needed
408-
added = self.mixed_float + series.astype('float32')
408+
added = mixed_float_frame + series.astype('float32')
409409
_check_mixed_float(added, dtype=dict(C=None))
410-
added = self.mixed_float + series.astype('float16')
410+
added = mixed_float_frame + series.astype('float16')
411411
_check_mixed_float(added, dtype=dict(C=None))
412412

413413
# these raise with numexpr.....as we are adding an int64 to an
414414
# uint64....weird vs int
415415

416-
# added = self.mixed_int + (100*series).astype('int64')
416+
# added = mixed_int_frame + (100*series).astype('int64')
417417
# _check_mixed_int(added, dtype = dict(A = 'int64', B = 'float64', C =
418418
# 'int64', D = 'int64'))
419-
# added = self.mixed_int + (100*series).astype('int32')
419+
# added = mixed_int_frame + (100*series).astype('int32')
420420
# _check_mixed_int(added, dtype = dict(A = 'int32', B = 'float64', C =
421421
# 'int32', D = 'int64'))
422422

423423
# TimeSeries
424-
ts = self.tsframe['A']
424+
ts = datetime_frame['A']
425425

426426
# 10890
427427
# we no longer allow auto timeseries broadcasting
428428
# and require explicit broadcasting
429-
added = self.tsframe.add(ts, axis='index')
429+
added = datetime_frame.add(ts, axis='index')
430430

431-
for key, col in compat.iteritems(self.tsframe):
431+
for key, col in compat.iteritems(datetime_frame):
432432
result = col + ts
433433
assert_series_equal(added[key], result, check_names=False)
434434
assert added[key].name == key
@@ -437,52 +437,52 @@ def test_combineSeries(self):
437437
else:
438438
assert result.name is None
439439

440-
smaller_frame = self.tsframe[:-5]
440+
smaller_frame = datetime_frame[:-5]
441441
smaller_added = smaller_frame.add(ts, axis='index')
442442

443-
tm.assert_index_equal(smaller_added.index, self.tsframe.index)
443+
tm.assert_index_equal(smaller_added.index, datetime_frame.index)
444444

445445
smaller_ts = ts[:-5]
446-
smaller_added2 = self.tsframe.add(smaller_ts, axis='index')
446+
smaller_added2 = datetime_frame.add(smaller_ts, axis='index')
447447
assert_frame_equal(smaller_added, smaller_added2)
448448

449449
# length 0, result is all-nan
450-
result = self.tsframe.add(ts[:0], axis='index')
451-
expected = DataFrame(np.nan, index=self.tsframe.index,
452-
columns=self.tsframe.columns)
450+
result = datetime_frame.add(ts[:0], axis='index')
451+
expected = DataFrame(np.nan, index=datetime_frame.index,
452+
columns=datetime_frame.columns)
453453
assert_frame_equal(result, expected)
454454

455455
# Frame is all-nan
456-
result = self.tsframe[:0].add(ts, axis='index')
457-
expected = DataFrame(np.nan, index=self.tsframe.index,
458-
columns=self.tsframe.columns)
456+
result = datetime_frame[:0].add(ts, axis='index')
457+
expected = DataFrame(np.nan, index=datetime_frame.index,
458+
columns=datetime_frame.columns)
459459
assert_frame_equal(result, expected)
460460

461461
# empty but with non-empty index
462-
frame = self.tsframe[:1].reindex(columns=[])
462+
frame = datetime_frame[:1].reindex(columns=[])
463463
result = frame.mul(ts, axis='index')
464464
assert len(result) == len(ts)
465465

466-
def test_combineFunc(self):
467-
result = self.frame * 2
468-
tm.assert_numpy_array_equal(result.values, self.frame.values * 2)
466+
def test_combineFunc(self, float_frame, mixed_float_frame):
467+
result = float_frame * 2
468+
tm.assert_numpy_array_equal(result.values, float_frame.values * 2)
469469

470470
# vs mix
471-
result = self.mixed_float * 2
471+
result = mixed_float_frame * 2
472472
for c, s in compat.iteritems(result):
473473
tm.assert_numpy_array_equal(
474-
s.values, self.mixed_float[c].values * 2)
474+
s.values, mixed_float_frame[c].values * 2)
475475
_check_mixed_float(result, dtype=dict(C=None))
476476

477-
result = self.empty * 2
478-
assert result.index is self.empty.index
477+
result = DataFrame() * 2
478+
assert result.index.equals(DataFrame().index)
479479
assert len(result.columns) == 0
480480

481-
def test_comparisons(self):
481+
def test_comparisons(self, simple_frame, float_frame):
482482
df1 = tm.makeTimeDataFrame()
483483
df2 = tm.makeTimeDataFrame()
484484

485-
row = self.simple.xs('a')
485+
row = simple_frame.xs('a')
486486
ndim_5 = np.ones(df1.shape + (1, 1, 1))
487487

488488
def test_comp(func):
@@ -493,17 +493,17 @@ def test_comp(func):
493493
with pytest.raises(ValueError, match='dim must be <= 2'):
494494
func(df1, ndim_5)
495495

496-
result2 = func(self.simple, row)
496+
result2 = func(simple_frame, row)
497497
tm.assert_numpy_array_equal(result2.values,
498-
func(self.simple.values, row.values))
498+
func(simple_frame.values, row.values))
499499

500-
result3 = func(self.frame, 0)
500+
result3 = func(float_frame, 0)
501501
tm.assert_numpy_array_equal(result3.values,
502-
func(self.frame.values, 0))
502+
func(float_frame.values, 0))
503503

504504
msg = 'Can only compare identically-labeled DataFrame'
505505
with pytest.raises(ValueError, match=msg):
506-
func(self.simple, self.simple[:2])
506+
func(simple_frame, simple_frame[:2])
507507

508508
test_comp(operator.eq)
509509
test_comp(operator.ne)
@@ -599,9 +599,9 @@ def test_boolean_comparison(self):
599599
with pytest.raises(ValueError, match=msg1d):
600600
result = df == tup
601601

602-
def test_combine_generic(self):
603-
df1 = self.frame
604-
df2 = self.frame.loc[self.frame.index[:-5], ['A', 'B', 'C']]
602+
def test_combine_generic(self, float_frame):
603+
df1 = float_frame
604+
df2 = float_frame.loc[float_frame.index[:-5], ['A', 'B', 'C']]
605605

606606
combined = df1.combine(df2, np.add)
607607
combined2 = df2.combine(df1, np.add)
@@ -611,8 +611,8 @@ def test_combine_generic(self):
611611
chunk = combined.loc[combined.index[:-5], ['A', 'B', 'C']]
612612
chunk2 = combined2.loc[combined2.index[:-5], ['A', 'B', 'C']]
613613

614-
exp = self.frame.loc[self.frame.index[:-5],
615-
['A', 'B', 'C']].reindex_like(chunk) * 2
614+
exp = float_frame.loc[float_frame.index[:-5],
615+
['A', 'B', 'C']].reindex_like(chunk) * 2
616616
assert_frame_equal(chunk, exp)
617617
assert_frame_equal(chunk2, exp)
618618

pandas/tests/series/test_analytics.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -387,8 +387,8 @@ def test_corr_invalid_method(self):
387387
# GH PR #22298
388388
s1 = pd.Series(np.random.randn(10))
389389
s2 = pd.Series(np.random.randn(10))
390-
msg = ("method must be either 'pearson', 'spearman', "
391-
"or 'kendall'")
390+
msg = ("method must be either 'pearson', "
391+
"'spearman', 'kendall', or a callable, ")
392392
with pytest.raises(ValueError, match=msg):
393393
s1.corr(s2, method="____")
394394

0 commit comments

Comments
 (0)