pandasのデータフレームの作り方で一番楽なのはどれなのか

アホなわたくしは、pandasを使うぞ、となった時、毎回使い方を忘れてしまいます。
なので、まずは小さいデータフレームを作成して、色々と使い方の確認を...
といきたいのですが、悲しいことにそもそもデータフレームの作り方すら忘れていることが常です。

従って、最低限のデータフレームの作り方と、どれが楽なのかをメモしておこうというのがこの記事です。
以下、pandasは`0.24.2`、pythonは`3,7,3`、`import pandas as pd`をしていることが前提です。

## 二次元配列から
こんな感じの二次元配列を準備。

```python

data = [
    ['2019-07-01 15:00:00','9997','740'],
    ['2019-07-02 15:00:00','9997','749'],
    ['2019-07-03 15:00:00','9997','757'],
    ['2019-07-04 15:00:00','9997','769'],
    ['2019-07-05 15:00:00','9997','762'],
    ['2019-07-08 15:00:00','9997','760']
]
```

二次元配列を元にデータを作成。

```python

df = pd.DataFrame(data)
print(df)
                     0     1    2
0  2019-07-01 15:00:00  9997  740
1  2019-07-02 15:00:00  9997  749
2  2019-07-03 15:00:00  9997  757
3  2019-07-04 15:00:00  9997  769
4  2019-07-05 15:00:00  9997  762
5  2019-07-08 15:00:00  9997  760
```




## csvから
こんな感じのcsv(a.csv)があったら

```bash:a.csv

2019-07-01 15:00:00,9997,740
2019-07-02 15:00:00,9997,749
2019-07-03 15:00:00,9997,757
2019-07-04 15:00:00,9997,769
2019-07-05 15:00:00,9997,762
2019-07-08 15:00:00,9997,760
```
`with open`とかしないで、コマンド一発で読み込みが可能。
ただし、自動的に１行目がヘッダ扱いになってしまうので、
データしかないcsvの場合はheaderを無し(header=None)にします。

```python

df = pd.read_csv('a.csv', header=None)
print(df)
                     0     1    2
0  2019-07-01 15:00:00  9997  740
1  2019-07-02 15:00:00  9997  749
2  2019-07-03 15:00:00  9997  757
3  2019-07-04 15:00:00  9997  769
4  2019-07-05 15:00:00  9997  762
5  2019-07-08 15:00:00  9997  760
```

## JSONから
こんな感じのJSON(a.json)があったら

```json:a.json
[
    {
        "date":"2019-07-01 15:00:00",
        "code":"9997",
        "close":"740"
    },
    {
        "date":"2019-07-02 15:00:00",
        "code":"9997",
        "close":"749"
    }
]
```
`pd.read_json`で読み込めるが、columnsがアルファベット順に並び替えられてしまいます。
これはPythonのdictが順序性を保証していない以上詮無きことのように思えるので、後から並び替えてやらねばなりません。
（因みに[Python3.7からはdictの順序性は保証される](https://docs.python.org/ja/3.7/library/stdtypes.html#typesmapping)ようです。がpandasがそれに対応することはなさそうですかね...）

```python

df = pd.read_json('a.json')
print(df)
   close  code                date
0    740  9997 2019-07-01 15:00:00
1    749  9997 2019-07-02 15:00:00

columns = ['date', 'code', 'close']
df = df[columns]
print(df)
                 date  code  close
0 2019-07-01 15:00:00  9997    740
1 2019-07-02 15:00:00  9997    749
```



## dictから
dictを絡めて作る方法も良く載っていますが、以下の方法だと縦方向のデータを横向きに書くのがしっくりきません。
（何より、文字数の多いcolumnが必然的に横に長くなるのがつらい）

```python

data = {
    'date':['2019-07-01 15:00:00','2019-07-02 15:00:00','2019-07-03 15:00:00','2019-07-04 15:00:00','2019-07-05 15:00:00','2019-07-08 15:00:00'],
    'code':['9997','9997','9997','9997','9997','9997'],
    'close':['740','749','757','769','762','760']
}
df = pd.DataFrame(data)
print(df)
                  date  code close
0  2019-07-01 15:00:00  9997   740
1  2019-07-02 15:00:00  9997   749
2  2019-07-03 15:00:00  9997   757
3  2019-07-04 15:00:00  9997   769
4  2019-07-05 15:00:00  9997   762
5  2019-07-08 15:00:00  9997   760
```
また、以下だとJSONの時と同様、列の順序が入れ替わってしまいます。

```python

data = [
    {'date':'2019-07-01 15:00:00','code':'9997','close':'740'},
    {'date':'2019-07-02 15:00:00','code':'9997','close':'749'},
    {'date':'2019-07-03 15:00:00','code':'9997','close':'757'},
    {'date':'2019-07-04 15:00:00','code':'9997','close':'769'},
    {'date':'2019-07-05 15:00:00','code':'9997','close':'762'},
    {'date':'2019-07-08 15:00:00','code':'9997','close':'760'}
]
df = pd.DataFrame(data)
print(df)
  close  code                 date
0   740  9997  2019-07-01 15:00:00
1   749  9997  2019-07-02 15:00:00
2   757  9997  2019-07-03 15:00:00
3   769  9997  2019-07-04 15:00:00
4   762  9997  2019-07-05 15:00:00
5   760  9997  2019-07-08 15:00:00
```

なので、動作確認用にちょろっと作るときは個人的には利用しません。

## (おまけ)indexとcolumnsについて

二次元配列の時やcsvの時のように、特にindexやcolumnを指定しない場合、
勝手に番号が割り振られますが、これはあとから変更できます。

```python

index = [f"day{d}" for d in range(1,7)]
columns = ['date', 'code', 'close']

df.index = index
df.columns = columns
print(df)
                     date  code close
day1  2019-07-01 15:00:00  9997   740
day2  2019-07-02 15:00:00  9997   749
day3  2019-07-03 15:00:00  9997   757
day4  2019-07-04 15:00:00  9997   769
day5  2019-07-05 15:00:00  9997   762
day6  2019-07-08 15:00:00  9997   760
```

二次元配列であれば、予めindexとcolumnsが決まっているならdf作成段階で与えてもOK。

```python

df = pd.DataFrame(data, index=index, columns=columns)
```

この列をindexにしたい、というのがあれば、後からそれを指定することも可能。

```python
df = df.set_index('date')
print(df)
                     code  close
date
2019-07-01 15:00:00  9997    740
2019-07-02 15:00:00  9997    749
```

## どれが楽か
csvなら適当にサクサク作れるし使い回しもできるしで、一番楽ですね。
どうしてもファイル保存したくない！という話であれば、dictよりはlistの方が分かりやすいかなぁと思いました。
文系なので、DataFrameとdictのデータの向きが違うだけで卒倒しそうです...。