向MultiIndex DataFrame/Series添加行
我在想,是否有一种方法可以像使用单一索引那样,给一个有多重索引的Series或DataFrame添加一行,也就是用 .ix 或 .loc 的方式?
我觉得自然的做法应该是这样的:
row_to_add = pd.MultiIndex.from_tuples()
df.ix[row_to_add] = my_row
但这样会出现一个KeyError错误。我知道我可以用 .append() 方法,但我觉得用 .ix[] 或 .loc[] 会更整洁。
这里有一个例子:
>>> df = pd.DataFrame({'Time': [dt.datetime(2013,2,3,9,0,1), dt.datetime(2013,2,3,9,0,1)], 'hsec': [1,25], 'vals': [45,46]})
>>> df
Time hsec vals
0 2013-02-03 09:00:01 1 45
1 2013-02-03 09:00:01 25 46
[2 rows x 3 columns]
>>> df.set_index(['Time','hsec'],inplace=True)
>>> ind = pd.MultiIndex.from_tuples([(dt.datetime(2013,2,3,9,0,2),0)],names=['Time','hsec'])
>>> df.ix[ind] = 5
Traceback (most recent call last):
File "<pyshell#201>", line 1, in <module>
df.ix[ind] = 5
File "C:\Program Files\Python27\lib\site-packages\pandas\core\indexing.py", line 96, in __setitem__
indexer = self._convert_to_indexer(key, is_setter=True)
File "C:\Program Files\Python27\lib\site-packages\pandas\core\indexing.py", line 967, in _convert_to_indexer
raise KeyError('%s not in index' % objarr[mask])
KeyError: "[(Timestamp('2013-02-03 09:00:02', tz=None), 0L)] not in index"
2 个回答
25
更新说明,因为 .ix
已经不再使用:
请改用 [DataFrame.loc][1]
:
# say you have dataframe x
x
Out[78]:
a b time
indA indB
a i 0.0 NaN 2018-09-12
b j 1.0 2.0 2018-10-12
c k 2.0 3.0 2018-11-12
f NaN NaN NaT
d i 5.0 NaN NaT
x.loc[('a','k'),:] = (3.5,6,pd.NaT)
x
Out[80]:
a b time
indA indB
a i 0.0 NaN 2018-09-12
b j 1.0 2.0 2018-10-12
c k 2.0 3.0 2018-11-12
f NaN NaN NaT
d i 5.0 NaN NaT
a k 3.5 6.0 NaT
26
要让多重索引正常工作,你必须指定一个元组(而且你还得把所有的轴都完全指定,比如:
是必须的)。
In [26]: df.ix[(dt.datetime(2013,2,3,9,0,2),0),:] = 5
In [27]: df
Out[27]:
vals
Time hsec
2013-02-03 09:00:01 1 45
25 46
2013-02-03 09:00:02 0 5
不过,重新索引或者拼接/添加一个新的数据框会更简单一些。一般来说,像这样扩展数据,只有在处理少量值的时候才有意义,因为这样做会生成一个副本。