索引 Dask DataFrame
目录
索引 Dask DataFrame¶
Dask DataFrame 支持 Pandas 的一些索引行为。
纯粹基于整数位置的索引,用于按位置选择。 |
|
纯粹基于标签位置的索引器,用于按标签选择。 |
基于标签的索引¶
与 Pandas 一样,Dask DataFrame 支持基于标签的索引,使用 .loc
访问器选择行或列,以及使用 __getitem__
(方括号)仅选择列。
注意
要选择行,DataFrame 的分界必须已知(更多信息请参阅 Dask DataFrame 设计 和 Dask DataFrame 最佳实践)。
>>> import dask.dataframe as dd
>>> import pandas as pd
>>> df = pd.DataFrame({"A": [1, 2, 3], "B": [3, 4, 5]},
... index=['a', 'b', 'c'])
>>> ddf = dd.from_pandas(df, npartitions=2)
>>> ddf
Dask DataFrame Structure:
A B
npartitions=1
a int64 int64
c ... ...
Dask Name: from_pandas, 1 tasks
选择列
>>> ddf[['B', 'A']]
Dask DataFrame Structure:
B A
npartitions=1
a int64 int64
c ... ...
Dask Name: getitem, 2 tasks
选择单个列会降级为 Dask Series
>>> ddf['A']
Dask Series Structure:
npartitions=1
a int64
c ...
Name: A, dtype: int64
Dask Name: getitem, 2 tasks
使用 .loc
切片行和(可选地)列
>>> ddf.loc[['b', 'c'], ['A']]
Dask DataFrame Structure:
A
npartitions=1
b int64
c ...
Dask Name: loc, 2 tasks
>>> ddf.loc[df["A"] > 1, ["B"]]
Dask DataFrame Structure:
B
npartitions=1
a int64
c ...
Dask Name: try_loc, 2 tasks
>>> ddf.loc[lambda df: df["A"] > 1, ["B"]]
Dask DataFrame Structure:
B
npartitions=1
a int64
c ...
Dask Name: try_loc, 2 tasks
Dask DataFrame 支持 Pandas 的 部分字符串索引
>>> ts = dd.demo.make_timeseries()
>>> ts
Dask DataFrame Structure:
id name x y
npartitions=11
2000-01-31 int64 object float64 float64
2000-02-29 ... ... ... ...
... ... ... ... ...
2000-11-30 ... ... ... ...
2000-12-31 ... ... ... ...
Dask Name: make-timeseries, 11 tasks
>>> ts.loc['2000-02-12']
Dask DataFrame Structure:
id name x y
npartitions=1
2000-02-12 00:00:00.000000000 int64 object float64 float64
2000-02-12 23:59:59.999999999 ... ... ... ...
Dask Name: loc, 12 tasks
基于位置的索引¶
Dask DataFrame 不跟踪分区的长度,这使得使用 .iloc
进行位置索引来选择行效率低下。DataFrame.iloc()
仅支持行索引器为 slice(None)
的索引器(:
是其简写)。
>>> ddf.iloc[:, [1, 0]]
Dask DataFrame Structure:
B A
npartitions=1
a int64 int64
c ... ...
Dask Name: iloc, 2 tasks
尝试使用 iloc
选择特定行会引发异常
>>> ddf.iloc[[0, 2], [1]]
Traceback (most recent call last)
File "<stdin>", line 1, in <module>
ValueError: 'DataFrame.iloc' does not support slicing rows. The indexer must be a 2-tuple whose first item is 'slice(None)'.
基于分区的索引¶
除了 pandas 风格的索引,Dask DataFrame 还支持使用 DataFrame.get_partition()
和 DataFrame.partitions
在分区级别进行索引。这些方法可用于按分区选择数据子集,而不是按整个 DataFrame 中的位置或索引标签进行选择。
使用 DataFrame.get_partition()
按位置选择单个分区。
>>> import dask
>>> ddf = dask.datasets.timeseries(start="2021-01-01", end="2021-01-07", freq="1h")
>>> ddf.get_partition(0)
Dask DataFrame Structure:
name id x y
npartitions=1
2021-01-01 object int64 float64 float64
2021-01-02 ... ... ... ...
Dask Name: get-partition, 2 graph layers
注意,结果也是一个 Dask DataFrame。
索引 DataFrame.partitions
来选择一个或多个分区。例如,您可以使用切片选择每隔一个分区
>>> ddf.partitions[::2]
Dask DataFrame Structure:
name id x y
npartitions=3
2021-01-01 object int64 float64 float64
2021-01-03 ... ... ... ...
2021-01-05 ... ... ... ...
2021-01-06 ... ... ... ...
Dask Name: blocks, 2 graph layers
或者甚至可以基于分区本身的数据进行更复杂的选择(代价是计算 DataFrame 直到该点为止)。例如,我们可以使用 DataFrame.map_partitions()
创建一个布尔掩码,其中包含唯一 ID 数量多于某个值的分区
>>> mask = ddf.id.map_partitions(lambda p: len(p.unique()) > 20).compute()
>>> ddf.partitions[mask]
Dask DataFrame Structure:
name id x y
npartitions=5
2021-01-01 object int64 float64 float64
2021-01-02 ... ... ... ...
... ... ... ... ...
2021-01-06 ... ... ... ...
2021-01-07 ... ... ... ...
Dask Name: blocks, 2 graph layers