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

时间:2014-01-22 00:11:34

标签: python pandas

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

data = data.sort(columns=["P_VALUE"], ascending=True, axis=0)

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

5 个答案:

答案 0 :(得分: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

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

sort --parallel=8 -t . -nrk3 stuff.csv

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

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

split -l 100000 stuff.csv stuff

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

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

sort -m sorted_stuff_* > final_sorted_stuff.csv

最后,如果您的文件不是CSV格式(比如它是tgz文件),那么您应该找到一种方法将其CSV版本管道传输到split

答案 1 :(得分:6)

正如我在评论中提到的那样,this answer已经提供了一种可能的解决方案。它基于HDF格式。

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

首先,您可以尝试直接使用pandas,querying the HDF-stored-DataFrame

其次,您可以使用PyTables,这是大熊猫使用的。

Francesc Alted在PyTables mailing list中提供了一个提示:

  

最简单的方法是将sortby参数设置为true   Table.copy()方法。这会触发磁盘上的排序操作,所以你   不要害怕你的可用记忆。你需要专业版   获得此功能的版本。

docs中,它说:

  

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

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

来自docs

  

表。 itersorted sortby,checkCSI = False,start = None,stop = None,step = None

     

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

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

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

简介

  

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

     

本笔记本是

的内存数据分析入门读物      
      
  • pandas:具有易于使用的数据结构和数据分析工具的库。此外,还有与SQLite等内存数据库的接口。
  •   
  • IPython notebook:用于编写和共享python代码,文本和绘图的界面。
  •   
  • SQLite:一个独立的无服务器数据库,可以很容易地从Pandas进行设置和查询。
  •   
  • Plotly:用于从Python发布精美互动图表的平台。
  •   

要求

import pandas as pd
from sqlalchemy import create_engine # database connection 

将CSV数据导入SQLite

  
      
  1. 将CSV(chunk-by-chunk)加载到DataFrame
  2. 中   
  3. 稍微处理数据,删除不感兴趣的列
  4.   
  5. 将其附加到SQLite数据库
  6.   
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

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

  

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

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

限制已排序条目的数量

  

每个城市最常见的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)

可能相关且有用的链接

答案 2 :(得分:3)

Blaze可能是您的工具,能够处理核心外的pandas和csv文件。 http://blaze.readthedocs.org/en/latest/ooc.html

import blaze
import pandas as pd
d = blaze.Data('my-large-file.csv')
d.P_VALUE.sort()  # Uses Chunked Pandas

为了加快处理速度,首先将其加载到数据库中,然后火焰可以控制。但如果这是一次性的,你有一些时间,那么发布的代码应该这样做。

答案 3 :(得分:1)

如果你的csv文件只包含结构化数据,我建议只使用linux命令。

假设csv文件包含两列,COL_1P_VALUE

map.py:

import sys
for line in sys.stdin:
    col_1, p_value = line.split(',')
    print "%f,%s" % (p_value, col_1)

然后以下linux命令将生成p_value已排序的csv文件:

cat input.csv | ./map.py | sort > output.csv

如果您熟悉hadoop,使用上面的map.py还添加一个简单的reduce.py将通过hadoop流系统生成已排序的csv文件。

答案 4 :(得分:0)

这是我诚实的建议。你可以做三个选择。

  1. 我喜欢Pandas丰富的文档和功能,但有人建议我这样做 使用NUMPY,因为它对较大的数据集感觉更快。您可以考虑使用其他工具以便更轻松地完成工作。

  2. 如果您使用的是Python3,您可以将大数据块分解为集合并执行Congruent Threading。我对此太懒了,它看起来很酷,你看Panda,Numpy,Scipy都是用硬件设计构思来构建我认为的多线程。

  3. 我更喜欢这个,这是简单而懒惰的技巧。对我来说。查看http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.sort.html

  4. 上的文档

    您还可以在您正在使用的pandas-sort函数中使用'kind'参数。

    Godspeed我的朋友。