pandas.DataFrameに１行ずつ書き足す早い方法を調べた

#### 何故やったか
pandas.DataFrameに１行ずつデータを書き出して行く処理を書いていたんですが、10万行ほど書き出すと結構遅くなっちゃいました。今後行数が増える予定なので、これを期にどう書くと早くなるか確認しておく事にしました。

#### やったこと
1. pandas.DataFrame.iloc[i, j] = hoge で１つずつ記入
- pandas.DataFrame.append(hoge) で１行まとめて追加
- pandas.DataFrame.iloc[i,:] = hoge で１行まとめて追加
- 1列ずつリストで作ってDataFrameに変換する※
※ 2018.11/12 kishiyamaさんに教えて頂いたやり方を追記

#### 試した環境
windows10 64bit
cpu: Ryzen7 1700X
gpu: GTX1080Ti
python3.6
jupyter 1.0.0
jupyter-client 5.2.3
jupyter-console 6.0.0
jupyter-core 4.4.0
Microsoft Edge 17.17134

#### 結論
1列ずつリストで作ってDataFrameに変換するやり方がメチャメチャ速い！
~~df.iloc[i, :] = listまたは df.iloc[i, :] = numpy.array が速い~~
※ 2018.11/12 kishiyamaさんに教えて頂いたやり方がめっちゃ速いので修正
![image.png](https://qiita-image-store.s3.amazonaws.com/0/277233/0685a1de-56a5-8012-47a5-14860a820cf6.png)


#### コードと実行結果


##### 1. pd.DataFrame.iloc[i, j] = hoge で１つずつ記入


```python
def test():
    log = pd.DataFrame([], columns=['A','B','C','D','E'], index=range(100))

    for i in range(100):
        log.iloc[i,0] = 'test'
        log.iloc[i,1] = ''
        log.iloc[i,2] = ''
        log.iloc[i,3] = 'test'
        log.iloc[i,4] = 'test'
    return(log)

%timeit log = test()

88.3 ms ± 2.64 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
```


遅い


##### 2-1. pd.DataFrame.append(hoge) で１行まとめて追加 (pandas.DataFrame)


```python
def test():
    log = pd.DataFrame([], columns=['A','B','C','D','E'])

    for _ in range(100):
        addRow = pd.DataFrame(['test','','','test','test'], index=log.columns).T
        log = log.append(addRow)
    
    return(log)

%timeit log = test()

59.6 ms ± 1.62 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
```


ちょっと速くなった


##### 2-2. pd.DataFrame.append(hoge) で１行まとめて追加 (pandas.Series)


```python
def test():
    log = pd.DataFrame([], columns=['A','B','C','D','E'])

    for _ in range(100):
        addRow = pd.Series(['test','','','test','test'], index=log.columns)
        log = log.append(addRow, ignore_index=True)
    
    return(log)

%timeit log = test()

131 ms ± 3.96 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
```


逆に遅くなっちゃう


##### 3-1. pandas.DataFrame.iloc[i,:] = hoge で１行まとめて追加 (pandas.Series)


```python
def test():
    log = pd.DataFrame([], columns=['A','B','C','D','E'], index=range(100))
    
    for i in range(100):
        addRow = pd.Series(['test','','','test','test'])
        log.iloc[i,:] = addRow
    
    return(log)

%timeit log = test()

70.4 ms ± 2.33 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
```


##### 3-2. pandas.DataFrame.iloc[i,:] = hoge で１行まとめて追加 (numpy.array)


```python
def test():
    log = pd.DataFrame([], columns=['A','B','C','D','E'], index=range(100))

    for i in range(100):
        addRow = np.array(['test','','','test','test'])
        log.iloc[i,:] = addRow

    return(log)

%timeit log = test()

20.1 ms ± 108 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
```


速い


##### 3-3. pandas.DataFrame.iloc[i,:] = hoge で１行まとめて追加 (list)


```python
def test():
    log = pd.DataFrame([], columns=['A','B','C','D','E'], index=range(100))

    for i in range(100):
        addRow = ['test','','','test','test']
        log.iloc[i,:] = addRow
    return(log)

%timeit log = test()

19.8 ms ± 216 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
```


速い


##### 4. 1列ずつリストで作ってDataFrameに変換する


```python
def test():
    a = []
    b = []
    c = []
    d = []
    e = []

    for i in range(100):
        a += ['test']
        b += ['']
        c += ['']
        d += ['test']
        e += ['test']

    return pd.DataFrame(
        data={'A': a, 'B': b, 'C': c, 'D': d, 'E': e},
        columns=['A', 'B', 'C', 'D', 'E']
    )
%timeit log = test()

1.58 ms ± 18.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
```


めっちゃ速


というわけで、リストで足し合わせておいてpd.DataFrame()に変換するやり方がめっちゃ速です。以前やってたやり方より50倍速いので、前回3日待った処理が1時間ちょいで完了できそう！