使用Numpy数组的Pandas MultiIndex查找

时间:2017-01-05 19:25:58

标签: python pandas numpy

我正在使用代表图表的pandas DataFrame。数据帧由指示节点端点的MultiIndex索引。

设定:

import pandas as pd
import numpy as np
import itertools as it
edges = list(it.combinations([1, 2, 3, 4], 2))

# Define a dataframe to represent a graph
index = pd.MultiIndex.from_tuples(edges, names=['u', 'v'])
df = pd.DataFrame.from_dict({
    'edge_id': list(range(len(edges))),
    'edge_weight': np.random.RandomState(0).rand(len(edges)),
})
df.index = index
print(df)
## -- End pasted text --
     edge_id  edge_weight
u v                      
1 2        0       0.5488
  3        1       0.7152
  4        2       0.6028
2 3        3       0.5449
  4        4       0.4237
3 4        5       0.6459

我希望能够使用边缘子集索引图形,这就是我选择使用MultiIndex的原因。只要df.loc的输入是元组列表,我就可以做到这一点。

# Select subset of graph using list-of-tuple indexing
edge_subset1 = [edges[x] for x in [0, 3, 2]]
df.loc[edge_subset1]
## -- End pasted text --
     edge_id  edge_weight
u v                      
1 2        0       0.5488
2 3        3       0.5449
1 4        2       0.6028

但是,当我的边缘列表是一个numpy数组(通常是这样)或列表列表时,我似乎无法使用df.loc属性。

# Why can't I do this if `edge_subset2` is a numpy array?
edge_subset2 = np.array(edge_subset1)
df.loc[edge_subset2]
## -- End pasted text --
TypeError: unhashable type: 'numpy.ndarray'

如果我可以只使用arr.tolist(),那就没问题,但这会导致看似不同的错误。

# Why can't I do this if `edge_subset2` is a numpy array?
# or if `edge_subset3` is a list-of-lists?
edge_subset3 = edge_subset2.tolist()
df.loc[edge_subset3]
## -- End pasted text --
TypeError: '[1, 2]' is an invalid key

每次我想选择一个子集时,必须使用list(map(tuple, arr.tolist()))真的很痛苦。如果有另一种方法可以做到这一点会很好。

主要任务是:

  • 为什么我不能使用.loc的numpy数组?是因为在引擎盖下使用字典将多索引标签映射到位置索引?

  • 为什么列表清单会出现不同的错误?也许它真的是同样的问题,只是采取了不同的方式?

  • 是否有另一种(理想情况下更简洁)的方法来查找数据帧的子集,其中包含我不知道的多索引标签数组?

1 个答案:

答案 0 :(得分:2)

字典键是不可变的,这基本上就是为什么你不能使用列表列表来访问多索引。

为了能够使用loc访问多索引数据,您需要将numpy数组转换为元组列表;元组是不可变的,一种方法是使用map,如你所提到的那样

如果您想避免使用地图,并且您正在从csv文件读取边缘,则可以将它们读入数据框,然后使用to_records属性设置为index { {1}}, 另一种方法是通过从False创建一个多索引,但你必须在传递之前转置列表,以便每个级别是数组中的一个列表

ndarray

我发现pandas文档中的文章advanced multi-indexing非常有用