2014-01-22 96 views
14

我想按給定列對數據進行排序,具體爲p值。但是,問題是我無法將全部數據加載到內存中。因此,以下內容不起作用或者僅適用於小數據集。在大型數據集中對熊貓進行排序

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

是否有一個快速的方式由給定列只需要大塊考慮,並不需要在內存中加載整個數據集,以我的數據進行排序?

+0

你的數據存儲在哪裏?多大?內存約束是什麼? – Jeff

+0

這是一對TB文件,集羣上的最大可用內存大約爲250 GB。 – user1867185

+0

以及如何存儲它;假設hdf? – Jeff

回答

10

過去,我使用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 

然後下面的命令將第三列進行排序的:

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

注意的數量這裏的線程設置爲8.


上面的內容適用於主內存中的文件。當你的文件太大時,你會首先將它分成許多部分。因此,

split -l 100000 stuff.csv stuff 

會將文件分割成長度至多爲100000行的文件。

現在您將按照上述方式單獨對每個文件進行排序。最後,你會用mergesort,再通過(waith吧...)sort

sort -m sorted_stuff_* > final_sorted_stuff.csv 

最後,如果你的文件不在CSV(說它是tgz文件),那麼你應該找到一種將CSV版本轉換爲split的方法。

+0

是否有必要在最後指定mergesort的排序順序,即'sort -nrk3 -m sorted_stuff_ *> final_sorted_stuff.csv'?如果沒有這個,我不相信,只是基於第一列進行排序,然後再向右進行排序呢? –

5

正如我在評論中提到的,this answer已經提供了一個可能的解決方案。它基於HDF格式。

關於排序問題,至少有三種可能的解決方法。

首先,您可以嘗試直接使用熊貓,querying the HDF-stored-DataFrame

其次,你可以使用PyTables,熊貓在引擎蓋下使用。

的Francesc Alted給出了在PyTables mailing list一個提示:

最簡單的方法是通過在 Table.copy()方法sortby參數設置爲true。這會觸發磁盤上的排序操作,因此您不必擔心可用內存。您將需要Pro 版本才能獲得此功能。

docs,它說:

sortby: 如果指定,並sortby對應於具有索引中的列,則副本會被這個指標進行排序。如果您想確保排序完整,則該指數必須是CSI指數。通過爲step關鍵字指定負值可以實現反向排序的副本。如果sortby被忽略或無,則使用原始表格順序

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

docs

表。 itersortedsortby,checkCSI =假,啓動=無,停止=無,步驟=無

迭代表數據以下sortby列的索引的順序。 sortby列必須關聯一個完整的索引。


另一種方法在於在之間使用數據庫。在IPython Notebook發佈在plot.ly可以看到詳細的工作流程。

這允許解決排序問題,與其它數據一起分析了是可能的熊貓。它看起來像是由用戶chris創建的,所以所有功勞都歸功於他。我在這裏複製相關部分。

介紹

這款筆記本探討了3.9GB CSV文件。

這款筆記本內存外的數據分析底漆

  • 大熊貓:通過易於使用的數據結構和數據分析工具庫。此外,與SQLite之類的內存不足數據庫的接口也是如此。
  • IPython的筆記本:寫作和共享Python代碼,文字和圖形的界面。
  • SQLite的:一個自包含的,無服務器的數據庫中,很容易建立從大熊貓和查詢。
  • Plotly:一個發佈美麗的互動圖形從Python到網絡的平臺。

要求

import pandas as pd 
from sqlalchemy import create_engine # database connection 

導入CSV數據到SQLite的

  1. 裝入CSV,塊逐塊,到數據幀
  2. 進程中的數據的bit,去掉無趣的列
  3. A PPEND它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) 

可能相關的和有用的鏈接

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 

爲加快處理速度時,它首先這開拓可以控制加載到數據庫中。但是,如果這是一個關閉,你有一段時間,那麼發佈的代碼應該這樣做。

0

這是我的誠實sugg./你可以做三個選項。

  1. 我喜歡大熊貓以其豐富的doc和功能,但我一直建議 使用numpy的,因爲它覺得比較快的更大的數據集。您也可以考慮使用其他工具以簡化工作。

  2. 如果你使用的是Python3,你可以將你的大數據塊分成集合並執行全同線程。我對此很懶惰,看起來很酷,你看到Panda,Numpy和Scipy都是用硬件設計的觀點來構建的,我相信它可以支持多線程。

  3. 我更喜歡這個,這很容易和懶惰的技術acc。對我來說。檢查文檔在http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.sort.html

您還可以使用在熊貓排序功能的「類」參數所使用。

Godspeed my friend。

+1

我想問你如何「感覺更快」顯示一些參考或例子。 'pandas'建立在'numpy'的頂部。它就像一個'numpy'數據分析風格的版本。只要做'df.values'來得到'numpy.array'。另外,'DataFrame.sort_values()'(鏈接的一個被棄用)使用'numpy.sort()'。查看代碼[here](https://github.com/pydata/pandas/blob/master/pandas/core/categorical.py)。當然,這可能會增加一些開銷,使用'numpy'(cpu時間,可能不是編程時間)可能稍微快一些,在這種情況下,您可以輕鬆訪問'numpy'對象。 – iled

+0

雖然Numpy是適合在內存中的問題工作的好工具,Numpy可以處理他正在與作者當前機器討論的問題的大小。 (這個記憶約束不在原始問題中。它在後面的評論中出現) – Back2Basics

+0

感謝您澄清和Back2Basics。多謝你們。 – Sampath

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 streamin生成排序後的csv文件g系統。