Pandas 新增欄位
在資料分析過程中,經常需要根據現有欄位計算出新的欄位。
範例資料
import pandas as pd
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie'],
'price': [100, 200, 150],
'quantity': [2, 3, 4]
})
新增固定值欄位
# 新增固定值
df['category'] = 'A'
print(df)
name price quantity category
0 Alice 100 2 A
1 Bob 200 3 A
2 Charlie 150 4 A
新增計算欄位
基本運算
# 新增計算欄位
df['total'] = df['price'] * df['quantity']
print(df)
name price quantity total
0 Alice 100 2 200
1 Bob 200 3 600
2 Charlie 150 4 600
多個欄位運算
df = pd.DataFrame({
'a': [1, 2, 3],
'b': [4, 5, 6],
'c': [7, 8, 9]
})
# 多欄位運算
df['sum'] = df['a'] + df['b'] + df['c']
df['avg'] = (df['a'] + df['b'] + df['c']) / 3
使用 assign()
assign() 會回傳新的 DataFrame,不修改原本的資料:
df = pd.DataFrame({
'price': [100, 200, 150],
'quantity': [2, 3, 4]
})
# 新增單一欄位
df_new = df.assign(total=df['price'] * df['quantity'])
# 新增多個欄位
df_new = df.assign(
total=df['price'] * df['quantity'],
tax=df['price'] * 0.05
)
# 使用 lambda(可以參考新建立的欄位)
df_new = df.assign(
total=lambda x: x['price'] * x['quantity'],
avg_price=lambda x: x['total'] / x['quantity']
)
條件欄位
使用 np.where()
import numpy as np
df['status'] = np.where(df['price'] > 150, 'high', 'low')
多條件
# 使用 np.select
conditions = [
df['price'] < 120,
df['price'] < 180,
df['price'] >= 180
]
choices = ['low', 'medium', 'high']
df['level'] = np.select(conditions, choices, default='unknown')
使用 apply()
def categorize(price):
if price < 120:
return 'low'
elif price < 180:
return 'medium'
else:
return 'high'
df['level'] = df['price'].apply(categorize)
從其他欄位組合
字串組合
df = pd.DataFrame({
'first_name': ['Alice', 'Bob'],
'last_name': ['Chen', 'Wang']
})
df['full_name'] = df['first_name'] + ' ' + df['last_name']
使用 f-string
df['display'] = df.apply(lambda x: f"{x['first_name']} ({x['last_name']})", axis=1)
插入欄位到特定位置
insert() 可以指定新欄位的位置:
df = pd.DataFrame({
'A': [1, 2, 3],
'C': [7, 8, 9]
})
# 在位置 1(第二個位置)插入新欄位
df.insert(1, 'B', [4, 5, 6])
print(df)
A B C
0 1 4 7
1 2 5 8
2 3 6 9
從 Series 新增
# 從另一個 Series 新增(會根據索引對齊)
s = pd.Series([10, 20, 30], index=[0, 1, 2])
df['new_col'] = s
複製欄位
df['price_copy'] = df['price']
# 或使用 copy 確保是獨立的副本
df['price_copy'] = df['price'].copy()
批次新增多個欄位
# 使用 assign
df = df.assign(
col1=1,
col2=2,
col3=df['a'] * 2
)
# 使用迴圈
for i in range(3):
df[f'new_{i}'] = i
刪除欄位
新增欄位後如果要刪除:
# 刪除單一欄位
df = df.drop('total', axis=1)
# 刪除多個欄位
df = df.drop(['total', 'tax'], axis=1)
# 使用 del
del df['total']
常見錯誤
SettingWithCopyWarning
# 可能產生警告
df[df['price'] > 100]['new'] = 1
# 正確方式:使用 loc
df.loc[df['price'] > 100, 'new'] = 1
這個警告是因為鏈式索引可能在副本上操作,而不是原始 DataFrame。使用 loc 可以確保直接在原始資料上操作。