【python】データフレームに直接データを指定する方法

pythonでpandasを使ってデータフレームを作成するにあたり、実践ではCSVなどファイルから入れることが多いと思うが、データの構造を理解したかったので直接データを指定する方法でいろいろと試してみた。

:::note
本記事に書いてあること：pandas（一部numpy）を使って、データフレームにデータをいれるコード
本記事に書いていないこと：使用したライブラリの説明
:::


# 必要なライプラリのインポート

まずはpandasを使えるようにインポート

```python
import pandas as pd
```

# データ構造の型

pythonでデータを扱うあたり、頻出のデータ構造についての説明。

- list:リスト型　複数の値を順序づけて保持するデータ型。インデックスを使って要素にアクセス
- Series:一次元のラベル付きデータ構造。（インデックスが数字じゃなくラベリングできる？）pandasライブラリで使える型。
- DataFrame:二次元ラベル付きデータ構造。行と列を持つテーブル形式。

# データを入れながら型を理解する

データ構造の型ごとにデータの入れ方を調べ、実施にコードを書いてデータの入り方を確認。

## list型

シンプルに[]で囲って書く。取り出す時はindex指定が必要なことに注意。

```python
dat_list = [1,20,39,49,47]
print(dat_list[0])
print(dat_list[1])
```

出力
```
1
20
```

## Series型

Seriesを`()`で定義して、その中でデータを`[]`で定義。
各データにインデックスラベルがつく

```python
dat = pd.Series([1,5,8,9,10])
print(dat)
```

出力
```
0     1
1     5
2     8
3     9
4    10
dtype: int64
```



## Dataframe型

本題となるDataframeの入れ方。2次元構造なので、入れ方がいろいろある。

`Dataframe()`で定義し,`()`の中にデータ構造をいれていく書き方。

本記事では、2次元リスト、Series型、辞書型、numpyの2次元配列を使った書き方を紹介。

### 2次元リストから作成

list型でデータを羅列すると、1行ずつ追加される

```python
df1 = pd.DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(df1)
```

出力
```
   0  1  2
0  1  2  3
1  4  5  6
2  7  8  9
```

データを[]で定義したあと、`columns=`で列にラベルをつけることもできる

```python
df1_label = pd.DataFrame([[1,2,3],[4,5,6],[7,8,9]],columns=['A','B','C']) 
print(df1_label)
```

出力
```
   A  B  C
0  1  2  3
1  4  5  6
2  7  8  9
```

### Series型を使って作成

listと同じように、Series型でデータを作り、羅列すると一行ずつ追加される

```python
data1 = pd.Series(['Alice','25','New York'])
data2 = pd.Series(['Bob',30,'Los Angels'])
data3 = pd.Series(['Charie',15,'Chicago'])

df_seriesdf = pd.DataFrame([data1,data2,data3])
df_seriesdf
```

出力
|	|0|	1|	2|
|--|--|--|--|
|0|	Alice|	25|	New York|
|1|	Bob|	30|	Los Angels|
|2|	Charie|	15|	Chicago|


### 辞書型から作成

#### 直接データフレーム内に定義する書き方

辞書型は`{}`で囲み、Key:Valueの形で書いていく
Keyが列名になる

```python
df2 = pd.DataFrame({
  'Name':['Taro','Jiro','Sabro'],
  'height':[167,182,178],
  'weight':[55.2,89.6,67.0]
})
print(df2)
```

出力
```
    Name  height  weight
0   Taro     167    55.2
1   Jiro     182    89.6
2  Sabro     178    67.0
```

#### 別オブジェクトで作成して引数として指定

辞書型のデータを別オブジェクトで作ってから、データフレームに引数をいれる

```python
data = {
  'Name':['Taro','Jiro','Sabro'],
  'height':[167,182,178],
  'weight':[55.2,89.6,67.0]
}
df2_dicdata = pd.DataFrame(data)
print(df2_dicdata)
```

出力
```
    Name  height  weight
0   Taro     167    55.2
1   Jiro     182    89.6
2  Sabro     178    67.0
```

#### ValueをSeries型で指定する

各列ごとにSeriesでデータオブジェクトを作成する
作成した各データオブジェクト名を、Valueで引数として指定

```python
names = pd.Series(['Alice','Bob','Chalie'])
ages = pd.Series([25,30,15])
cities = pd.Series(['New York','Los Angels','Chicago'])

df3 = pd.DataFrame({
  'Name': names,
  'Age':ages,
  'City':cities
})

print(df3)

```

出力
```
     Name  Age        City
0   Alice   25    New York
1     Bob   30  Los Angels
2  Chalie   15     Chicago
```

### numpy配列で定義

numpyの二次元配列データ構造を使ってデータオブジェクトを作成。
list型と同じ考え方で、データを`[]`で囲って指定
データフレームに引数をいれる

```python
import numpy as np

data = np.array([
  ['Alice',25,'New York'],
  ['Bob',30,'Los Angels'],
  ['Charie',25,'Chicago']
])
data
```

出力
```
array([['Alice', '25', 'New York'],
       ['Bob', '30', 'Los Angels'],
       ['Charie', '25', 'Chicago']], dtype='<U21')
```

列名も指定してつけてみた。

```python
df4 = pd.DataFrame(data,columns=['Name','Age','City'])
print(df4)
```

出力
```
     Name  Age        City
0   Alice   25    New York
1     Bob   30  Los Angels
2  Chalie   15     Chicago
```


### （応用）index名を明示的に指定して作成

まず辞書型でデータを作成し、データフレームに引数として入れると同時に、各行にindex名をつける。

```python
data ={
  'Age':[25,30,25],
  'City':['New York','Los Angels','Chicago']
}

df5 = pd.DataFrame(data,index=['Alice','Bob','Charie'])
print(df5)
```

出力
```
        Age        City
Alice    25    New York
Bob      30  Los Angels
Charie   25     Chicago
```

#### （応用）indexを振り直す

データを集計して扱う時は、それぞれのデータ行にindexの番号が振り直されていないと集計ができないことがあるので、reset.index()で各行にindexをつける

```python
df5 = df5.reset_index()
df5
```

出力
| |index|	Age|City|
|---|---|---|---|
|0|	Alice|	25|	New York|
|1|	Bob|	30|	Los Angels|
|2|	Charie|	25|	Chicago|

#### （応用）index振りなおしたデータの列に名前をつける
上記のままだと、名前の列名が「index」のままなので、列名を「Name」に変える

```python
df5 = df5.rename(columns={'index':'Name'})
df5
```

出力
|	|Name|	Age|	City|
|---|---|---|---|
|0|	Alice|	25|	New York|
|1|	Bob|	30|	Los Angels|
|2|	Charie|	25|	Chicago|

# まとめ

行ごとにデータを入れる時はlist型を使った二次元リストで直接指定や、Series型でnumpyの配列`array`を使うのがよさそう。

列ごとにデータを入れる時は辞書型を使うとできそう。（列ごとに指定して、ということはあまりないと思うが）