将Series.map
与Series参数一起使用,我可以获取Series的元素并将它们用作另一个Series的索引。我想对DataFrame的一些列做同样的事情,将每一行作为一组索引级别用于MultiIndex-ed系列。这是一个例子:
>>> d = pandas.DataFrame([["A", 1], ["B", 2], ["C", 3]], columns=["X", "Y"])
>>> d
X Y
0 A 1
1 B 2
2 C 3
[3 rows x 2 columns]
>>> s = pandas.Series(np.arange(9), index=pandas.MultiIndex.from_product([["A", "B", "C"], [1, 2, 3]]))
>>> s
A 1 0
2 1
3 2
B 1 3
2 4
3 5
C 1 6
2 7
3 8
dtype: int32
我希望能够做d.map(s)
,以便d
的每一行都应该被视为用于索引s
的MultiIndex的元组。也就是说,我想要与此相同的结果:
>>> s.ix[[("A", 1), ("B", 2), ("C", 3)]]
A 1 0
B 2 4
C 3 8
dtype: int32
但是,与Series不同,DataFrame没有map
方法。另一个明显的替代方法s.ix[d]
给出了错误“无法使用多维键进行索引”,因此显然也不支持。
我知道我可以通过将DataFrame转换为列表列表,或者使用逐行apply
来逐个抓取每个项目来实现,但如果没有任何方法可以做到这一点开销量是多少?如何一次在多个列上执行等效的Series.map
?
答案 0 :(得分:2)
您可以使用以下方法从DataFrame和ix / loc创建MultiIndex:
In [11]: mi = pd.MultiIndex.from_arrays(d.values.T)
In [12]: s.loc[mi] # can use ix too
Out[12]:
A 1 0
B 2 4
C 3 8
dtype: int64
这非常有效:
In [21]: s = pandas.Series(np.arange(1000*1000), index=pandas.MultiIndex.from_product([range(1000), range(1000)]))
In [22]: d = pandas.DataFrame(zip(range(1000), range(1000)), columns=["X", "Y"])
In [23]: %timeit mi = pd.MultiIndex.from_arrays(d.values.T); s.loc[mi]
100 loops, best of 3: 2.77 ms per loop
In [24]: %timeit s.apply(lambda x: x + 1) # at least compared to apply
1 loops, best of 3: 3.14 s per loop