MultiIndex 查找给定级别具有给定值的所有索引
MultiIndex look up all indices that have a given value for a given level
我正在使用 pandas.Series
和 MultiIndex
进行双向加权查找。我认为使用 MultiIndex 也应该很容易找到给定级别的相应其他级别,但我找不到一个简单的函数 other
来执行如下操作:
>>> index=pandas.MultiIndex.from_tuples(
... [(0, 0),(1,2),(3,4),(5,6),(5,7),(8,0),(9,0)],
... names=["concept", "word"])
>>> other(index, "word", 0)
{0, 8, 9}
>>> other(index, "concept", 3)
{4}
>>> other(index, "word", 6)
{5}
我很乐意指定关卡编号而不是关卡名称,并获取任何可迭代对象,不一定是集合。我只有一个2级的多指标,所以我不关心如何泛化到更高层次的多指标,甚至不关心它是否泛化。
如果这涉及遍历 MultiIndex 中的所有条目并比较它们,我会有点不高兴,因为我认为索引有点像多键哈希表。
这个怎么样:
>>> index.get_level_values('concept').values[index.get_level_values('word').values == 0]
array([0, 8, 9])
>>> index.get_level_values('concept').values[index.get_level_values('word').values == 6]
array([5])
>>> index.get_level_values('word').values[index.get_level_values('concept').values == 3]
array([4])
请注意,您可以轻松地将 numpy 数组转换为集合:
>>> set(np.array([1, 2, 3]))
{1, 2, 3}
并将以上所有内容包装到某个函数中 other
应该不是很困难。
方法一:
您可以使用矢量化方法构建自定义函数,如下所示:
def other(index, slicing, value):
arr = np.column_stack(index.values.tolist())
return (np.delete(arr, slicing, axis=0)[0][arr[slicing]==value])
用法:
other(index, slicing=index.names.index('word'), value=0)
# array([0, 8, 9])
时间:
%timeit other(index, slicing=index.names.index('word'), value=0)
10000 loops, best of 3: 43.9 µs per loop
方法二:
如果你想使用一个内置的方法,它只通过将值插入相应的参数来给你结果,你可以选择 get_loc_level
,它给你一个标签对应的整数位置切片,比如所以:
演示:
index.get_loc_level(key=3, level='concept')[1].ravel()
# array([4], dtype=int64)
index.get_loc_level(key=0, level='word')[1].ravel()
# array([0, 8, 9], dtype=int64)
index.get_loc_level(key=6, level='word')[1].ravel()
# array([5], dtype=int64)
时间:
%timeit index.get_loc_level(key=0, level='word')[1].ravel()
10000 loops, best of 3: 129 µs per loop
因此,使用自定义函数而不是使用实现可获得 3 倍的提升
给定的 2 级多索引 DF
的内置方法。
我正在使用 pandas.Series
和 MultiIndex
进行双向加权查找。我认为使用 MultiIndex 也应该很容易找到给定级别的相应其他级别,但我找不到一个简单的函数 other
来执行如下操作:
>>> index=pandas.MultiIndex.from_tuples(
... [(0, 0),(1,2),(3,4),(5,6),(5,7),(8,0),(9,0)],
... names=["concept", "word"])
>>> other(index, "word", 0)
{0, 8, 9}
>>> other(index, "concept", 3)
{4}
>>> other(index, "word", 6)
{5}
我很乐意指定关卡编号而不是关卡名称,并获取任何可迭代对象,不一定是集合。我只有一个2级的多指标,所以我不关心如何泛化到更高层次的多指标,甚至不关心它是否泛化。
如果这涉及遍历 MultiIndex 中的所有条目并比较它们,我会有点不高兴,因为我认为索引有点像多键哈希表。
这个怎么样:
>>> index.get_level_values('concept').values[index.get_level_values('word').values == 0]
array([0, 8, 9])
>>> index.get_level_values('concept').values[index.get_level_values('word').values == 6]
array([5])
>>> index.get_level_values('word').values[index.get_level_values('concept').values == 3]
array([4])
请注意,您可以轻松地将 numpy 数组转换为集合:
>>> set(np.array([1, 2, 3]))
{1, 2, 3}
并将以上所有内容包装到某个函数中 other
应该不是很困难。
方法一:
您可以使用矢量化方法构建自定义函数,如下所示:
def other(index, slicing, value):
arr = np.column_stack(index.values.tolist())
return (np.delete(arr, slicing, axis=0)[0][arr[slicing]==value])
用法:
other(index, slicing=index.names.index('word'), value=0)
# array([0, 8, 9])
时间:
%timeit other(index, slicing=index.names.index('word'), value=0)
10000 loops, best of 3: 43.9 µs per loop
方法二:
如果你想使用一个内置的方法,它只通过将值插入相应的参数来给你结果,你可以选择 get_loc_level
,它给你一个标签对应的整数位置切片,比如所以:
演示:
index.get_loc_level(key=3, level='concept')[1].ravel()
# array([4], dtype=int64)
index.get_loc_level(key=0, level='word')[1].ravel()
# array([0, 8, 9], dtype=int64)
index.get_loc_level(key=6, level='word')[1].ravel()
# array([5], dtype=int64)
时间:
%timeit index.get_loc_level(key=0, level='word')[1].ravel()
10000 loops, best of 3: 129 µs per loop
因此,使用自定义函数而不是使用实现可获得 3 倍的提升
给定的 2 级多索引 DF
的内置方法。