索引 Dask DataFrame

Dask DataFrame 支持 Pandas 的一些索引行为。

DataFrame.iloc

纯基于位置的整数索引,用于按位置选择。

DataFrame.loc

纯标签位置索引器,用于按标签选择。

基于标签的索引

就像 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 系列:

>>> 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) 的索引器(其中 :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