我想按给定列对数据进行排序,特别是p值。但是,问题是我无法将整个数据加载到内存中。因此,以下内容不起作用或者仅适用于小型数据集。
data = data.sort(columns=["P_VALUE"], ascending=True, axis=0)
是否有一种快速方法可以按给定列对数据进行排序,该列只考虑块并且不需要在内存中加载整个数据集?
答案 0 :(得分:16)
过去,我使用了Linux的一对值得尊敬的sort
和split
实用程序来排序大量窒息大熊猫的文件。
我不想贬低此页面上的其他答案。但是,由于您的数据是文本格式(正如您在评论中所指出的那样),我认为开始将其转换为其他格式(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
参数设置为trueTable.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(chunk-by-chunk)加载到DataFrame
中- 稍微处理数据,删除不感兴趣的列
- 将其附加到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
住房和发展部受到的投诉最多
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_1
和P_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)
这是我诚实的建议。你可以做三个选择。
我喜欢Pandas丰富的文档和功能,但有人建议我这样做 使用NUMPY,因为它对较大的数据集感觉更快。您可以考虑使用其他工具以便更轻松地完成工作。
如果您使用的是Python3,您可以将大数据块分解为集合并执行Congruent Threading。我对此太懒了,它看起来很酷,你看Panda,Numpy,Scipy都是用硬件设计构思来构建我认为的多线程。
我更喜欢这个,这是简单而懒惰的技巧。对我来说。查看http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.sort.html
您还可以在您正在使用的pandas-sort函数中使用'kind'参数。
Godspeed我的朋友。