我有一个如下的多索引系列。
> data = [['a', 'X', 'u', 1], ['a', 'X', 'v', 2], ['b', 'Y', 'u', 4], ['a', 'Z', 'u', 20]]
> s = pd.DataFrame(data, columns='one two three four'.split()).set_index('one two three'.split()).four
> s
one two three
a X u 1
v 2
b Y u 4
a Z u 20
Name: four, dtype: int64
然后第二个系列仅以one
和three
作为索引:
>>> data2 = [['a', 'u', 3], ['a', 'v', -3]]
>>> s2 = pd.DataFrame(data2, columns='one three four'.split()).set_index('one three'.split()).four
>>> s2
one three
a u 3
v -3
Name: four, dtype: int64
据我所知,s2
和s.loc[pd.IndexSlice[:, 'X', :]]
的索引是相同的。
因此,我希望能够做到:
>>> s.loc[pd.IndexSlice[:, 'X', :]] = s2
,但这样做会产生NaN
值:
>>> s
one two three
a X u NaN
v NaN
b Y u 4.0
a Z u 20.0
Name: four, dtype: float64
正确的方法是什么?
答案 0 :(得分:3)
pandas
有时,MultiIndexes有点漏洞,感觉就像其中一种情况。如果您修改s2.index
以匹配s.index
,则分配有效:
In [155]: s2.index = pd.MultiIndex.from_product([['a'], ['X'], ['u', 'v']], names=['one', 'two', 'three'])
In [156]: s2
Out[156]:
one two three
a X u 3
v -3
Name: four, dtype: int64
In [157]: s
Out[157]:
one two three
a X u 1
v 2
b Y u 4
a Z u 20
Name: four, dtype: int64
In [158]: s.loc[:, 'X', :] = s2
In [159]: s
Out[159]:
one two three
a X u 3
v -3
b Y u 4
a Z u 20
Name: four, dtype: int64
可能值得在https://github.com/pandas-dev/pandas/issues中搜索类似的问题,如果还不存在,请将其添加为新的问题。
同时,另一种选择是使用.unstack()
重塑数据以进行分配:
In [181]: s = s.unstack('two')
In [182]: s['X'].loc[s2.index] = s2
In [183]: s.stack().swaplevel(1,2).sort_index()
Out[183]:
one two three
a X u 3.0
v -3.0
Z u 20.0
b Y u 4.0
dtype: float64
答案 1 :(得分:0)
作为@randy答案的替代方法,您可以将s2
转换为列表,因此您不必关心索引匹配(但是,它不会像join
那样只是一个双方的分配保留顺序):
>>> s.loc[pd.IndexSlice[:, 'X', :]]=s2.to_list()
>>> s
one two three
a X u 3.0
v -3.0
b Y u 4.0
a Z u 20.0
Name: four, dtype: float64