Dask DataFrame的等价于pandas DataFrame的sort_values函数

14

对于dask DataFrame,sort_values在pandas中有什么等效的替代方法?我正在尝试使用dask DataFrame来扩展一些由内存问题造成的Pandas代码。

等效方法是:

ddf.set_index([col1, col2], sorted=True)

?

3个回答

12

在并行环境下进行排序很困难。在Dask.dataframe中,您有两个选项。

set_index

目前,您可以使用单列索引调用set_index:

In [1]: import pandas as pd

In [2]: import dask.dataframe as dd

In [3]: df = pd.DataFrame({'x': [3, 2, 1], 'y': ['a', 'b', 'c']})

In [4]: ddf = dd.from_pandas(df, npartitions=2)

In [5]: ddf.set_index('x').compute()
Out[5]: 
   y
x   
1  c
2  b
3  a

Unfortunately dask.dataframe does not (as of November 2016) support multi-column indexes

In [6]: ddf.set_index(['x', 'y']).compute()
NotImplementedError: Dask dataframe does not yet support multi-indexes.
You tried to index with this index: ['x', 'y']
Indexes must be single columns only.

最大的n个数

根据您提出问题的方式,我怀疑这不适用于您,但通常使用排序的情况可以通过更便宜的解决方案nlargest来解决。

In [7]: ddf.x.nlargest(2).compute()
Out[7]: 
0    3
1    2
Name: x, dtype: int64

In [8]: ddf.nlargest(2, 'x').compute()
Out[8]: 
   x  y
0  3  a
1  2  b

谢谢Matthew。如果我事先知道数据框的行数,那么nlargest就可以正常工作了吧? - femibyte
4
nlargest返回一个dask.dataframe的单个分区,因此通常不是排序的好方法。 - MRocklin
那么,对所有分区应用排序操作并获得最终结果,哪种方式是比较好的呢? - Koustav Chanda

5

我更喜欢使用Dask的单个列进行set_index,然后使用map_partitions来分发Pandas的sort_values

# Prepare data
import dask
import dask.dataframe as dd
data = dask.datasets.timeseries()

# Sort by 'name' and 'id'
data = data.set_index('name')
data = data.map_partitions(lambda df: df.sort_values(['name', 'id']))

一个可能的问题是,单个索引值不能存在于多个分区中。但根据我的实践观察,Dask似乎不会允许这种情况发生。不过最好对此有一个更加可靠的意见。

编辑:我已在Dask dataframe: Can a single index be in multiple partitions?上提出了这个问题。


1
您可以使用此代码添加一个新的复合列并为其设置索引:
newcol = ddf.col1 + "|" + ddf.col2
ddf = ddf.assign(ind=newcol)
ddf = ddf.set_index('ind', sorted=True)

如果数据框已经按照(col1, col2)排序,则它也已经按照newcol排序,因此您可以使用sorted=True。

6
我不相信这样会生效——sorted=True 表示你向 Dask 承诺索引已经被排序,而并不是要求 Dask 对其进行排序。参见 https://github.com/dask/dask/issues/2388。 - goodside
我已经修正了解释,它不够清晰。谢谢。 - negas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接