Skip to content

Commit a8f66b4

Browse files
committed
ENH: DataFrame.insert method implementation
1 parent 783e629 commit a8f66b4

File tree

3 files changed

+41
-7
lines changed

3 files changed

+41
-7
lines changed

pandas/core/frame.py

+24-5
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,7 @@ def __setitem__(self, key, value):
717717

718718
self._boolean_set(key, value)
719719
else:
720-
self._insert_item(key, value)
720+
self._set_item(key, value)
721721

722722
def _boolean_set(self, key, value):
723723
mask = key.values
@@ -729,7 +729,23 @@ def _boolean_set(self, key, value):
729729

730730
self.values[mask] = value
731731

732-
def _insert_item(self, key, value):
732+
def insert(self, loc, column, value):
733+
"""
734+
Insert column into DataFrame at specified location. Raises Exception if
735+
column is already contained in the DataFrame
736+
737+
Parameters
738+
----------
739+
loc : int
740+
Must have 0 <= loc <= len(columns)
741+
column : object
742+
value : int, Series, or array-like
743+
"""
744+
value = self._sanitize_column(value)
745+
value = np.atleast_2d(value) # is this a hack?
746+
self._data.insert(loc, column, value)
747+
748+
def _set_item(self, key, value):
733749
"""
734750
Add series to DataFrame in specified column.
735751
@@ -739,9 +755,13 @@ def _insert_item(self, key, value):
739755
Series/TimeSeries will be conformed to the DataFrame's index to
740756
ensure homogeneity.
741757
"""
758+
value = self._sanitize_column(value)
759+
value = np.atleast_2d(value) # is this a hack?
760+
self._data.set(key, value)
761+
762+
def _sanitize_column(self, value):
742763
# Need to make sure new columns (which go into the BlockManager as new
743764
# blocks) are always copied
744-
745765
if hasattr(value, '__iter__'):
746766
if isinstance(value, Series):
747767
if value.index.equals(self.index):
@@ -761,8 +781,7 @@ def _insert_item(self, key, value):
761781
else:
762782
value = np.repeat(value, len(self.index))
763783

764-
value = np.atleast_2d(value)
765-
self._data.set(key, value)
784+
return value
766785

767786
def __delitem__(self, key):
768787
"""

pandas/core/internals.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -490,9 +490,9 @@ def set(self, item, value):
490490
block.set(item, value)
491491
else:
492492
# insert at end
493-
self.insert(item, len(self.items), value)
493+
self.insert(len(self.items), item, value)
494494

495-
def insert(self, item, loc, value):
495+
def insert(self, loc, item, value):
496496
if item in self.items:
497497
raise Exception('cannot insert %s, already exists' % item)
498498

pandas/tests/test_frame.py

+15
Original file line numberDiff line numberDiff line change
@@ -977,6 +977,21 @@ def test_toString(self):
977977
frame = self.klass(index=np.arange(1000))
978978
frame.toString(buf=buf)
979979

980+
def test_insert(self):
981+
df = DataFrame(np.random.randn(5, 3), index=np.arange(5),
982+
columns=['c', 'b', 'a'])
983+
984+
df.insert(0, 'foo', df['a'])
985+
self.assert_(np.array_equal(df.columns, ['foo', 'c', 'b', 'a']))
986+
assert_almost_equal(df['a'], df['foo'])
987+
988+
df.insert(2, 'bar', df['c'])
989+
self.assert_(np.array_equal(df.columns, ['foo', 'c', 'bar', 'b', 'a']))
990+
assert_almost_equal(df['c'], df['bar'])
991+
992+
self.assertRaises(Exception, df.insert, 1, 'a')
993+
self.assertRaises(Exception, df.insert, 1, 'c')
994+
980995
def test_delitem(self):
981996
del self.frame['A']
982997
self.assert_('A' not in self.frame)

0 commit comments

Comments
 (0)