通过使用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
Run Code Online (Sandbox Code Playgroud)
我想做的是d.map(s)
,因此每行d
都应作为一个元组,用于索引的MultiIndex s
。也就是说,我想要与此相同的结果:
>>> s.ix[[("A", 1), ("B", 2), ("C", 3)]]
A 1 0
B 2 4
C 3 8
dtype: int32
Run Code Online (Sandbox Code Playgroud)
但是,与Series不同,DataFrame没有map
方法。另一个明显的选择,s.ix[d]
给我错误“无法用多维键索引”,因此显然也不支持。
我知道我可以通过将DataFrame转换为列表列表,或通过逐行apply
抓取每个项目来做到这一点,但是没有那么多的开销没有办法吗?我如何Series.map
一次等效于多个列?
您可以使用以下方法从 DataFrame 和 ix/loc 创建 MultiIndex:
\n\nIn [11]: mi = pd.MultiIndex.from_arrays(d.values.T)\n\nIn [12]: s.loc[mi] #\xc2\xa0can use ix too\nOut[12]:\nA 1 0\nB 2 4\nC 3 8\ndtype: int64\n
Run Code Online (Sandbox Code Playgroud)\n\n这是非常有效的:
\n\nIn [21]: s = pandas.Series(np.arange(1000*1000), index=pandas.MultiIndex.from_product([range(1000), range(1000)]))\n\nIn [22]: d = pandas.DataFrame(zip(range(1000), range(1000)), columns=["X", "Y"])\n\nIn [23]: %timeit mi = pd.MultiIndex.from_arrays(d.values.T); s.loc[mi]\n100 loops, best of 3: 2.77 ms per loop\n\nIn [24]: %timeit s.apply(lambda x: x + 1) # at least compared to apply\n1 loops, best of 3: 3.14 s per loop\n
Run Code Online (Sandbox Code Playgroud)\n