Skip to content

Commit 92f0234

Browse files
committed
BUG: always raise exception when concat keys aren't found in passed levels, close #1406
1 parent 682ca25 commit 92f0234

File tree

3 files changed

+53
-22
lines changed

3 files changed

+53
-22
lines changed

pandas/core/factor.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# pylint: disable=E1101,W0232
22

33
import numpy as np
4+
5+
from pandas.core.algorithms import factorize
46
import pandas.core.common as com
57

68

@@ -51,8 +53,6 @@ def __init__(self, labels, levels, name=None):
5153

5254
@classmethod
5355
def from_array(cls, data):
54-
from pandas.core.algorithms import factorize
55-
5656
try:
5757
labels, levels, _ = factorize(data, sort=True)
5858
except TypeError:

pandas/tools/merge.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,7 +1131,11 @@ def _make_concat_multiindex(indexes, keys, levels=None, names=None):
11311131
for hlevel, level in zip(zipped, levels):
11321132
to_concat = []
11331133
for key, index in zip(hlevel, indexes):
1134-
i = level.get_loc(key)
1134+
try:
1135+
i = level.get_loc(key)
1136+
except KeyError:
1137+
raise ValueError('Key %s not in level %s' % (str(key), str(level)))
1138+
11351139
to_concat.append(np.repeat(i, len(index)))
11361140
label_list.append(np.concatenate(to_concat))
11371141

@@ -1146,8 +1150,11 @@ def _make_concat_multiindex(indexes, keys, levels=None, names=None):
11461150
levels.append(factor.levels)
11471151
label_list.append(factor.labels)
11481152

1149-
# also copies
1150-
names = names + _get_consensus_names(indexes)
1153+
if len(names) == len(levels):
1154+
names = list(names)
1155+
else:
1156+
# also copies
1157+
names = names + _get_consensus_names(indexes)
11511158

11521159
return MultiIndex(levels=levels, labels=label_list, names=names)
11531160

@@ -1165,7 +1172,14 @@ def _make_concat_multiindex(indexes, keys, levels=None, names=None):
11651172
# do something a bit more speedy
11661173

11671174
for hlevel, level in zip(zipped, levels):
1175+
hlevel = _ensure_index(hlevel)
11681176
mapped = level.get_indexer(hlevel)
1177+
1178+
mask = mapped == -1
1179+
if mask.any():
1180+
raise ValueError('Values not found in passed level: %s'
1181+
% str(hlevel[mask]))
1182+
11691183
new_labels.append(np.repeat(mapped, n))
11701184

11711185
if isinstance(new_index, MultiIndex):

pandas/tools/tests/test_merge.py

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,6 +1144,35 @@ def test_concat_keys_and_levels(self):
11441144
self.assertEqual(result.index.names, ['first', 'second'] + [None])
11451145
self.assert_(np.array_equal(result.index.levels[0], ['baz', 'foo']))
11461146

1147+
def test_concat_keys_levels_no_overlap(self):
1148+
# GH #1406
1149+
df = DataFrame(np.random.randn(1, 3), index=['a'])
1150+
df2 = DataFrame(np.random.randn(1, 4), index=['b'])
1151+
1152+
self.assertRaises(ValueError, concat, [df, df],
1153+
keys=['one', 'two'], levels=[['foo', 'bar', 'baz']])
1154+
1155+
self.assertRaises(ValueError, concat, [df, df2],
1156+
keys=['one', 'two'], levels=[['foo', 'bar', 'baz']])
1157+
1158+
1159+
def test_concat_rename_index(self):
1160+
a = DataFrame(np.random.rand(3,3),
1161+
columns=list('ABC'),
1162+
index=Index(list('abc'), name='index_a'))
1163+
b = DataFrame(np.random.rand(3,3),
1164+
columns=list('ABC'),
1165+
index=Index(list('abc'), name='index_b'))
1166+
1167+
result = concat([a, b], keys=['key0', 'key1'],
1168+
names=['lvl0', 'lvl1'])
1169+
1170+
exp = concat([a, b], keys=['key0', 'key1'], names=['lvl0'])
1171+
exp.index.names[1] = 'lvl1'
1172+
1173+
tm.assert_frame_equal(result, exp)
1174+
self.assertEqual(result.index.names, exp.index.names)
1175+
11471176
def test_crossed_dtypes_weird_corner(self):
11481177
columns = ['A', 'B', 'C', 'D']
11491178
df1 = DataFrame({'A' : np.array([1, 2, 3, 4], dtype='f8'),
@@ -1163,6 +1192,11 @@ def test_crossed_dtypes_weird_corner(self):
11631192
columns=columns)
11641193
tm.assert_frame_equal(appended, expected)
11651194

1195+
df = DataFrame(np.random.randn(1, 3), index=['a'])
1196+
df2 = DataFrame(np.random.randn(1, 4), index=['b'])
1197+
result = concat([df, df2], keys=['one', 'two'], names=['first', 'second'])
1198+
self.assertEqual(result.index.names, ['first', 'second'])
1199+
11661200
def test_handle_empty_objects(self):
11671201
df = DataFrame(np.random.randn(10, 4), columns=list('abcd'))
11681202

@@ -1334,23 +1368,6 @@ def test_concat_exclude_none(self):
13341368
tm.assert_frame_equal(result, df)
13351369
self.assertRaises(Exception, concat, [None, None])
13361370

1337-
def test_concat_rename_index(self):
1338-
a = DataFrame(np.random.rand(3,3),
1339-
columns=list('ABC'),
1340-
index=Index(list('abc'), name='index_a'))
1341-
b = DataFrame(np.random.rand(3,3),
1342-
columns=list('ABC'),
1343-
index=Index(list('abc'), name='index_b'))
1344-
1345-
result = concat([a, b], keys=['key0', 'key1'],
1346-
names=['lvl0', 'lvl1'])
1347-
1348-
exp = concat([a, b], keys=['key0', 'key1'], names=['lvl0'])
1349-
exp.index.names[1] = 'lvl1'
1350-
1351-
tm.assert_frame_equal(result, exp)
1352-
self.assertEqual(result.index.names, exp.index.names)
1353-
13541371
class TestOrderedMerge(unittest.TestCase):
13551372

13561373
def setUp(self):

0 commit comments

Comments
 (0)