2016-07-07 12 views
0

14個のデータフレームと25万個以上の行を持つ14個のデータフレームがあります。 データフレームには同じ列ヘッダーがあり、データフレームを行ごとにマージしたいと考えています。私はデータフレームを「成長中の」DataFrameに連結しようとしましたが、それは数時間かかりました。効率的にパンダのデータフレームを行単位で結合する

基本的に、私は13回以下のようなものやっていた:

DF = pd.DataFrame() 
for i in range(13): 
    DF = pd.concat([DF, subDF]) 

をstackoverflowの答えhereはリストにすべてのサブデータフレームを追加して、サブデータフレームのリストを連結示唆しています。このような何かやっように聞こえる

DF = pd.DataFrame() 
lst = [subDF, subDF, subDF....subDF] #up to 13 times 
for subDF in lst: 
    DF = pd.concat([DF, subDF]) 

は、彼らは同じものではありませんか?おそらく、私は提案されたワークフローを誤解しています。ここで私がテストしたものがあります。

import numpy 
import pandas as pd 
import timeit 

def test1(): 
    "make all subDF and then concatenate them" 
    numpy.random.seed(1) 
    subDF = pd.DataFrame(numpy.random.rand(1)) 
    lst = [subDF, subDF, subDF] 
    DF = pd.DataFrame() 
    for subDF in lst: 
     DF = pd.concat([DF, subDF], axis=0,ignore_index=True) 

def test2(): 
    "add each subDF to the collecitng DF as you're making the subDF" 
    numpy.random.seed(1) 
    DF = pd.DataFrame() 
    for i in range(3): 
     subDF = pd.DataFrame(numpy.random.rand(1)) 
     DF = pd.concat([DF, subDF], axis=0,ignore_index=True) 

print('test1() takes {0} sec'.format(timeit.timeit(test1, number=1000))) 
print('test2() takes {0} sec'.format(timeit.timeit(test2, number=1000))) 

>> Output 

test1() takes 12.732409087137057 sec 
test2() takes 15.097430311612698 sec 

私は、複数のデータフレーム行単位を連結するための効率的な方法でご提案をいただければ幸いです。ありがとう!

+0

データを追加して1つのCSVにドロップしてから、そのCSVをDFとして読んでいると思いましたか?数時間かかるはずです。 – Merlin

答えて

3

すべてのデータフレームのリストを作成します。

dfs = [] 
for i in range(13): 
    df = ... # However it is that you create your dataframes 
    dfs.append(df) 

その後1話の一挙にそれらを連結:それは正確に14データフレームを作成するため

merged = pd.concat(dfs) # add ignore_index=True if appropriate 

これはあなたのコードよりもはるかに高速である(あなたのオリジナルの13プラスmerged)、あなたのコードでは26個のオリジナルの13個の中間マージが作成されます。

編集:

テストコードのバリエーションは次のとおりです。

import numpy 
import pandas as pd 
import timeit 

def test_gen_time(): 
    """Create three large dataframes, but don't concatenate them""" 
    for i in range(3): 
     df = pd.DataFrame(numpy.random.rand(10**6)) 

def test_sequential_concat(): 
    """Create three large dataframes, concatenate them one by one""" 
    DF = pd.DataFrame() 
    for i in range(3): 
     df = pd.DataFrame(numpy.random.rand(10**6)) 
     DF = pd.concat([DF, df], ignore_index=True) 

def test_batch_concat(): 
    """Create three large dataframes, concatenate them at the end""" 
    dfs = [] 
    for i in range(3): 
     df = pd.DataFrame(numpy.random.rand(10**6)) 
     dfs.append(df) 
    DF = pd.concat(dfs, ignore_index=True) 

print('test_gen_time() takes {0} sec' 
      .format(timeit.timeit(test_gen_time, number=200))) 
print('test_sequential_concat() takes {0} sec' 
      .format(timeit.timeit(test_sequential_concat, number=200))) 
print('test_batch_concat() takes {0} sec' 
      .format(timeit.timeit(test_batch_concat, number=200))) 

出力:

test_gen_time() takes 10.095820872998956 sec 
test_sequential_concat() takes 17.144756617000894 sec 
test_batch_concat() takes 12.99131180600125 sec 

ライオンのシェアは、データフレームを生成に対応しています。バッチ連結は約2.9秒かかる。シーケンシャル連結には7秒以上かかります。

+0

素晴らしい点。これは時間を半分にします! – sedeh

+0

@sedehこの回答または任意の回答があなたの質問を解決した場合、チェックマークをクリックして[受諾](http://meta.stackexchange.com/q/5234/179419)を検討してください。これは、あなたが解決策を見つけ出し、回答者とあなた自身の両方に評判を与えていることを広範なコミュニティに示します。これを行う義務はありません。 –

関連する問題