DataFrame 雙維度資料
# Pandas DataFrame 簡介
`DataFrame` 是 Pandas 中最常用的**雙維度資料結構**,可以想成 Excel 工作表或資料庫中的一張表格。
它具有:
- **列(rows)**:每一筆資料
- **欄(columns)**:資料欄位
- **索引(index)**:每一列的標籤,預設為 `0, 1, 2, ...`
- 不同欄位可以有不同的資料型別,例如整數、文字、日期等
- 每一個欄位本質上是一個 `Series`
```python
import pandas as pd
df = pd.DataFrame({
"姓名": ["小明", "小華", "小美"],
"年齡": [20, 21, 19],
"成績": [85, 92, 78]
})
print(df)
```
輸出:
```text
姓名 年齡 成績
0 小明 20 85
1 小華 21 92
2 小美 19 78
```
---
# 常見的建立 DataFrame 方式
## 1. 使用字典建立
字典的 key 會成為欄位名稱,value 通常是串列。
```python
df = pd.DataFrame({
"name": ["Amy", "Bob", "Cindy"],
"age": [20, 22, 21]
})
```
也可以指定索引:
```python
df = pd.DataFrame(
{
"name": ["Amy", "Bob", "Cindy"],
"age": [20, 22, 21]
},
index=["A001", "B001", "C001"]
)
```
---
## 2. 使用「字典串列」建立
每個字典代表一筆資料,適合處理類似 JSON 的資料。
```python
data = [
{"name": "Amy", "score": 85},
{"name": "Bob", "score": 90},
{"name": "Cindy", "score": 78}
]
df = pd.DataFrame(data)
```
如果不同字典缺少某些欄位,Pandas 會以 `NaN` 補上。
---
## 3. 使用二維串列或 NumPy 陣列建立
```python
data = [
["Amy", 20],
["Bob", 22],
["Cindy", 21]
]
df = pd.DataFrame(data, columns=["name", "age"])
```
搭配 NumPy:
```python
import numpy as np
array = np.array([
[1, 80],
[2, 90],
[3, 75]
])
df = pd.DataFrame(array, columns=["id", "score"])
```
---
## 4. 從檔案或資料庫讀取
常見的資料來源包括 CSV、Excel、SQL 等。
```python
df = pd.read_csv("sales.csv")
df = pd.read_excel("sales.xlsx")
```
從 SQL 查詢:
```python
df = pd.read_sql("SELECT * FROM students", connection)
```
---
# DataFrame 的索引操作
## 1. 查看索引與欄位
```python
df.index # 查看列索引
df.columns # 查看欄位名稱
df.shape # 查看列數與欄數
```
---
## 2. 取出欄位
取出單一欄位:
```python
df["score"]
```
結果是 `Series`。
取出多個欄位:
```python
df[["name", "score"]]
```
結果仍是 `DataFrame`。
也可以使用屬性方式,但欄位名稱必須符合 Python 變數命名規則:
```python
df.score
```
通常建議使用 `df["score"]`,較明確也較安全。
---
## 3. 使用 `loc` 依照「索引標籤」選取
`loc` 是以索引名稱及欄位名稱選取資料。
```python
df.loc["A001"]
```
取得指定索引的資料:
```python
df.loc["A001", "name"]
```
取得指定索引、指定多個欄位:
```python
df.loc[["A001", "B001"], ["name", "age"]]
```
使用條件篩選:
```python
df.loc[df["score"] >= 80, ["name", "score"]]
```
`loc` 的切片範圍通常包含結束標籤:
```python
df.loc["A001":"C001"]
```
---
## 4. 使用 `iloc` 依照「位置」選取
`iloc` 使用從 `0` 開始的整數位置。
```python
df.iloc[0] # 第 1 列
df.iloc[0, 1] # 第 1 列、第 2 欄
df.iloc[:2, :2] # 前 2 列、前 2 欄
```
`iloc` 的切片規則和 Python 一樣,結束位置不包含:
```python
df.iloc[0:2]
```
代表取第 0、1 列,不包含第 2 列。
---
## 5. 修改資料
修改單一儲存格:
```python
df.loc["A001", "score"] = 95
```
依位置修改:
```python
df.iloc[0, 1] = 95
```
新增欄位:
```python
df["passed"] = df["score"] >= 60
```
---
## 6. 新增、刪除與重設索引
新增一列:
```python
df.loc["D001"] = ["David", 23, 88]
```
刪除欄位:
```python
df = df.drop(columns=["age"])
```
刪除指定索引的列:
```python
df = df.drop(index=["A001"])
```
將某個欄位設定為索引:
```python
df = df.set_index("name")
```
將索引還原成一般欄位:
```python
df = df.reset_index()
```
排序索引:
```python
df = df.sort_index()
```
排序欄位值:
```python
df = df.sort_values("score", ascending=False)
```
---
# 實務範例:學生分數分析
```python
students = pd.DataFrame({
"學號": ["S001", "S002", "S003", "S004"],
"姓名": ["小明", "小華", "小美", "小強"],
"國文": [85, 72, 90, 60],
"數學": [88, 65, 95, 70]
})
# 設定學號為索引
students = students.set_index("學號")
# 計算平均分數
students["平均"] = students[["國文", "數學"]].mean(axis=1)
# 找出平均分數達 80 分以上的學生
excellent = students.loc[students["平均"] >= 80, ["姓名", "平均"]]
print(excellent)
```
找出數學成績最高的學生:
```python
top_student = students.iloc[students["數學"].argmax()]
print(top_student)
```
這裡使用了:
- `set_index()` 設定索引
- `mean(axis=1)` 計算每列平均
- `loc` 進行條件篩選
- `iloc` 依照位置取得資料
---
## 重點整理
| 操作目的 | 常用語法 |
|---|---|
| 取單一欄位 | `df["欄位名"]` |
| 取多個欄位 | `df[["欄位1", "欄位2"]]` |
| 依索引標籤選取 | `df.loc[...]` |
| 依位置選取 | `df.iloc[...]` |
| 設定索引 | `df.set_index()` |
| 重設索引 | `df.reset_index()` |
| 新增欄位 | `df["新欄位"] = ...` |
| 刪除列或欄 | `df.drop()` |
| 排序 | `df.sort_values()`、`df.sort_index()` |
`DataFrame` 的核心概念就是:以「列索引」和「欄位名稱」管理表格資料,並透過 `loc`、`iloc` 及條件運算快速選取、修改與分析資料。
相關學習地圖、教學課程
Python 資料工程