在大熊猫中为大型数据集排序

use*_*185 19 python pandas

我想按给定列对数据进行排序,特别是p值.但是,问题是我无法将整个数据加载到内存中.因此,以下内容不起作用或者仅适用于小型数据集.

data = data.sort(columns=["P_VALUE"], ascending=True, axis=0)
Run Code Online (Sandbox Code Playgroud)

是否有一种快速方法可以按给定列对数据进行排序,该列只考虑块并且不需要在内存中加载整个数据集?

Ami*_*ory 16

在过去,我用linux的一对古老的sortsplit实用工具,到哽咽大熊猫大量文件进行排序.

我不想贬低这个页面上的其他答案.但是,由于您的数据是文本格式(正如您在评论中所指出的那样),我认为开始将其转换为其他格式(HDF,SQL等)是非常复杂的,因为GNU/Linux实用程序已经解决了这个问题.有效地持续了30到40年.


说你的文件被调用stuff.csv,看起来像这样:

4.9,3.0,1.4,0.6
4.8,2.8,1.3,1.2
Run Code Online (Sandbox Code Playgroud)

然后,以下命令将按第3列对其进行排序:

sort --parallel=8 -t . -nrk3 stuff.csv
Run Code Online (Sandbox Code Playgroud)

请注意,此处的线程数设置为8.


以上将适用于适合主存储器的文件.当您的文件太大时,您首先会将其拆分为多个部分.所以

split -l 100000 stuff.csv stuff
Run Code Online (Sandbox Code Playgroud)

将文件拆分为长度最多为100000行的文件.

现在,您将单独对每个文件进行排序,如上所述.最后,你将使用mergesort,再次通过(waith for it ...)sort:

sort -m sorted_stuff_* > final_sorted_stuff.csv
Run Code Online (Sandbox Code Playgroud)

最后,如果您的文件不是CSV(比如它是一个tgz文件),那么您应该找到一种方法来管理它的CSV版本split.


ile*_*led 6

正如我在评论中提到的,这个答案已经提供了一个可能的解决方案.它基于HDF格式.

关于排序问题,使用该方法至少有三种可能的方法来解决它.

首先,您可以尝试直接使用pandas,查询HDF-stored-DataFrame.

其次,你可以使用PyTables,大熊猫在引擎盖下使用.

Francesc Alted在PyTables邮件列表中给出了一个提示:

最简单的方法是sortbyTable.copy()方法中将参数设置为true .这会触发磁盘上的排序操作,因此您不必担心可用内存.您需要专业版才能获得此功能.

文档中,它说:

sortby: 如果指定,并且sortby对应于具有索引的列,则副本将按此索引排序.如果要确保完全排序的订单,索引必须是CSI.可以通过为step关键字指定负值来实现反向排序的副本.如果省略sortby或None,则使用原始表顺序

第三,仍然使用PyTables,您可以使用该方法Table.itersorted().

来自文档:

表.itersorted(sortby,checkCSI = False,start = None,stop = None,step = None)

按照sortby列索引的顺序迭代表数据.sortby列必须具有关联的完整索引.


另一种方法是在两者之间使用数据库.详细的工作流程可以在plot.ly上发布的这个IPython Notebook看到.

这允许解决排序问题,以及大熊猫可能进行的其他数据分析.它看起来像是由用户chris创建的,所以所有的功劳归于他.我在这里复制相关部分.

介绍

这款笔记本探索了一个3.9Gb的CSV文件.

这款笔记本是关于内存数据分析的入门读物

  • pandas:具有易于使用的数据结构和数据分析工具的库.此外,还有像SQLite这样的内存数据库的接口.
  • IPython notebook:用于编写和共享python代码,文本和绘图的接口.
  • SQLite:一个独立的,无服务器的数据库,易于从Pandas进行设置和查询.
  • Plotly:一个用于从Python发布漂亮的交互式图形到Web的平台.

要求

import pandas as pd
from sqlalchemy import create_engine # database connection 
Run Code Online (Sandbox Code Playgroud)

将CSV数据导入SQLite

  1. 将CSV(chunk-by-chunk)加载到DataFrame中
  2. 稍微处理数据,删除不感兴趣的列
  3. 将其附加到SQLite数据库
disk_engine = create_engine('sqlite:///311_8M.db') # Initializes database with filename 311_8M.db in current directory

chunksize = 20000
index_start = 1

for df in pd.read_csv('311_100M.csv', chunksize=chunksize, iterator=True, encoding='utf-8'):

    # do stuff   

    df.index += index_start

    df.to_sql('data', disk_engine, if_exists='append')
    index_start = df.index[-1] + 1
Run Code Online (Sandbox Code Playgroud)

查询值计数并对结果进行排序

住房和发展部受到的投诉最多

df = pd.read_sql_query('SELECT Agency, COUNT(*) as `num_complaints`'
                       'FROM data '
                       'GROUP BY Agency '
                       'ORDER BY -num_complaints', disk_engine)
Run Code Online (Sandbox Code Playgroud)

限制排序条目的数量

每个城市最常见的10个投诉是什么?

df = pd.read_sql_query('SELECT City, COUNT(*) as `num_complaints` '
                            'FROM data '
                            'GROUP BY `City` '
                   'ORDER BY -num_complaints '
                   'LIMIT 10 ', disk_engine)
Run Code Online (Sandbox Code Playgroud)

可能相关且有用的链接