我有像这样的数据框
+----+------------+------------+------------+
| | | type | payment |
+----+------------+------------+------------+
| id | res_number | | |
+----+------------+------------+------------+
| a | 1 | toys | 20000 |
| | 2 | clothing | 30000 |
| | 3 | food | 40000 |
| b | 4 | food | 40000 |
| | 5 | laptop | 30000 |
+----+------------+------------+------------+
因为你可以看到id,而res_number是分层行值,而type,payment是普通列值。我想得到的是下面的内容。
array([['toys', 20000],
['clothing', 30000],
['food', 40000]])
它的编号为' id(= a)'无论什么' res_number'来了,我知道
df.loc[['a']].values
完美适用于它。但索引的速度太慢了......我必须索引150000个值。
所以我按
索引数据框df.iloc[1].values
但它只带来了
array(['toys', 20000])
在索引层次结构时,是否有更快的索引方法?
答案 0 :(得分:4)
选项1
pd.DataFrame.xs
df.xs('a').values
选项2
pd.DataFrame.loc
df.loc['a'].values
选项3
pd.DataFrame.query
df.query('ilevel_0 == \'a\'').values
选项4
更多回旋,使用pd.MultiIndex.get_level_values
创建一个掩码:
df[df.index.get_level_values(0) == 'a'].values
array([['toys', 20000],
['clothing', 30000],
['food', 40000]], dtype=object)
答案 1 :(得分:1)
将.loc与轴参数
一起使用 df.loc(axis=0)['a',:].values
输出:
array([['toys', 20000],
['clothing', 30000],
['food', 40000]], dtype=object)
答案 2 :(得分:0)
另一种选择。保留每组的开始和结束索引的额外字典。 ( 假设索引已排序。 )
选项1 使用组中的第一个和最后一个索引与iloc
进行查询。
d = {k: slice(v[0], v[-1]+1) for k, v in df.groupby("id").indices.items()}
df.iloc[d["b"]]
array([['food', 40000],
['laptop', 30000]], dtype=object)
选项2 使用第一个和最后一个索引在numpy
上使用df.values
的索引切片进行查询。
df.values[d["a"]]
时序
df_testing = pd.DataFrame({"id": [str(v) for v in np.random.randint(0, 100, 150000)],
"res_number": np.arange(150000),
"payment": [v for v in np.random.randint(0, 100000, 150000)]}
).set_index(["id","res_number"]).sort_index()
d = {k: slice(v[0], v[-1]+1) for k, v in df_testing.groupby("id").indices.items()}
# by COLDSPEED
%timeit df_testing.xs('5').values
303 µs ± 17.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
# by OP
%timeit df_testing.loc['5'].values
358 µs ± 22.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
# Tai 1
%timeit df_testing.iloc[d["5"]].values
130 µs ± 3.04 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
# Tai 2
%timeit df_testing.values[d["5"]]
7.26 µs ± 845 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
然而,获得d
并非无成本。
%timeit {k: slice(v[0], v[-1]+1) for k, v in df_testing.groupby("id").indices.items()}
16.3 ms ± 6.89 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)
是否值得创建额外的查找表?
创建索引的成本将根据查询的收益进行分摊。在我的玩具数据集中,它将是16.3 ms /(300 us - 7 us)≈56个查询来恢复创建索引的成本。
同样,索引需要排序。