Pandas 提供了多種便捷的資料操作方式,其中 loc 和 iloc 是兩種重要的索引器,允許我們以標籤或位置索引資料。理解這兩種索引器的差異和用法,對於有效地操作 DataFrame 至關重要。此外,Pandas 支援使用 NumPy 的通用函式,可以直接對 DataFrame 進行元素級運算,並保留索引,方便後續分析。在進行不同 DataFrame 或 Series 之間的運算時,Pandas 會自動進行索引對齊,確保運算的正確性,但需要注意缺失值的處理。熟練掌握這些技巧,能大幅提升資料處理效率。
資料選擇在 DataFrame 中
Python 的一個重要原則是「明確比隱含好」。這種明確的性質使得 loc 和 iloc 在維護乾淨和可讀的程式碼時非常有用,特別是在整數索引的情況下,使用它們可以防止由混合索引/切片約定引起的隱藏 bug。
DataFrame 作為字典
首先,我們將 DataFrame 視為一組相關的 Series 物件的字典。讓我們回到我們之前的例子,該例子中包含了各州的面積和人口資料:
import pandas as pd
# 定義面積和人口的 Series
area = pd.Series({'California': 423967, 'Texas': 695662,
'Florida': 170312, 'New York': 141297,
'Pennsylvania': 119280})
pop = pd.Series({'California': 39538223, 'Texas': 29145505,
'Florida': 21538187, 'New York': 20201249,
'Pennsylvania': 13002700})
# 建立 DataFrame
data = pd.DataFrame({'area': area, 'pop': pop})
print(data)
輸出結果:
area pop
California 423967 39538223
Texas 695662 29145505
Florida 170312 21538187
New York 141297 20201249
Pennsylvania 119280 13002700
個別的 Series 可以透過字典風格的索引來存取,方法是使用欄位名稱。例如,要存取 area 欄位的 Series,可以使用 data['area']。這種方法使得資料選擇變得更加直觀和方便。
內容解密:
在上面的程式碼中,我們首先定義了兩個 Series:area 和 pop,分別代表各州的面積和人口資料。然後,我們建立了一個 DataFrame data,其中包含了這兩個 Series 作為欄位。最後,我們列印預出 DataFrame 的內容。
這種方法展示瞭如何將 DataFrame 視為一組相關的 Series 物件的字典,並如何透過字典風格的索引來存取個別的 Series。這種方法在資料分析和處理中非常有用,因為它允許我們以更直觀和方便的方式選擇和操作資料。
圖表翻譯:
在這個圖表中,我們展示了 DataFrame 和 Series 之間的關係。DataFrame 包含多個 Series,每個 Series 都代表了一個欄位(在這個例子中是面積和人口)。每個 Series 都儲存了相應的資料(各州的面積和人口資料)。這種結構使得資料選擇和操作變得更加方便和直觀。
使用 Pandas DataFrame 進行資料操作
當我們處理資料時,經常需要存取和操作資料中的特定欄位。Pandas 的 DataFrame 提供了多種方法來實作這一功能。
存取欄位
假設我們有一個 DataFrame data,其中包含多個欄位,包括 area 和 pop。我們可以使用以下方法存取這些欄位:
# 使用字典式存取
print(data['area'])
# 使用屬性式存取(當欄位名稱為字串時)
print(data.area)
這兩種方法都可以用來存取 DataFrame 中的欄位,但是屬性式存取有一個限制:當欄位名稱不是字串時,或者當欄位名稱與 DataFrame 的方法名稱衝突時,屬性式存取就不適用了。例如,DataFrame 有一個 pop 方法,所以 data.pop 會指向這個方法,而不是 pop 欄位。
# 屬性式存取與字典式存取的比較
print(data.pop is data["pop"]) # Output: False
修改欄位
我們可以使用字典式語法來修改 DataFrame 中的欄位。例如,新增一個新欄位 density,其值為 pop 欄位除以 area 欄位:
# 新增新欄位
data['density'] = data['pop'] / data['area']
這種語法不僅可以用於新增新欄位,也可以用於修改現有的欄位。
範例程式碼
import pandas as pd
# 建立示例DataFrame
data = pd.DataFrame({
'area': [423967, 695662, 170312, 141297, 119280],
'pop': [39461588, 28995881, 21244317, 19453561, 12802038]
}, index=['California', 'Texas', 'Florida', 'New York', 'Pennsylvania'])
# 新增新欄位:density
data['density'] = data['pop'] / data['area']
print(data)
圖表翻譯
內容解密
上述範例程式碼建立了一個包含 area 和 pop 欄位的 DataFrame,然後增加了一個新的 density 欄位,其值為 pop 欄位除以 area 欄位。這個過程展示瞭如何使用 Pandas DataFrame 進行資料操作和新增欄位。
資料分析與操作
在進行資料分析時,瞭解資料的結構和內容是非常重要的。以下將展示如何使用 Pandas 進行資料操作和分析。
資料預覽
首先,我們可以預覽資料的內容。假設我們有一個 DataFrame,包含了美國各州的面積、人口和人口密度等資訊。
| 州名 | 面積 | 人口 | 人口密度 |
|---|---|---|---|
| California | 423967 | 39538223 | 93.257784 |
| Texas | 695662 | 29145505 | 41.896072 |
| Florida | 170312 | 21538187 | 126.463121 |
| New York | 141297 | 20201249 | 142.970120 |
| Pennsylvania | 119280 | 13002700 | 109.009893 |
資料操作
Pandas 提供了多種方式來操作資料。例如,我們可以使用 element-by-element 的方式進行算術運算。
DataFrame 作為二維陣列
我們也可以將 DataFrame 視為一個二維陣列。這樣,我們就可以使用陣列的操作方法來處理資料。
import pandas as pd
import numpy as np
# 建立一個 DataFrame
data = pd.DataFrame({
'州名': ['California', 'Texas', 'Florida', 'New York', 'Pennsylvania'],
'面積': [423967, 695662, 170312, 141297, 119280],
'人口': [39538223, 29145505, 21538187, 20201249, 13002700],
'人口密度': [93.257784, 41.896072, 126.463121, 142.970120, 109.009893]
})
# 顯示 DataFrame 的值
print(data.values)
輸出結果:
[[4.23967000e+05 3.95382230e+07 9.32577842e+01]
[6.95662000e+05 2.91455050e+07 4.18960717e+01]
[1.70312000e+05 2.15381870e+07 1.26463121e+02]
[1.41297000e+05 2.02012490e+07 1.42970120e+02]
[1.19280000e+05 1.30027000e+07 1.09009893e+02]]
轉置 DataFrame
我們可以使用 T 屬性來轉置 DataFrame。
# 轉置 DataFrame
print(data.T)
輸出結果:
州名 California Texas Florida New York Pennsylvania
面積 4.239670e+05 6.956620e+05 1.703120e+05 1.412970e+05 1.192800e+05
人口 3.953822e+07 2.914550e+07 2.153819e+07 2.020125e+07 1.300270e+07
人口密度 9.325778e+01 4.189607e+01 1.264631e+02 1.429701e+02 1.090099e+02
資料索引
我們可以使用索引來存取 DataFrame 中的資料。
# 存取一行資料
print(data.values[0])
輸出結果:
[4.23967000e+05 3.95382230e+07 9.32577842e+01]
# 存取一列資料
print(data['面積'])
輸出結果:
California 423967
Texas 695662
Florida 170312
New York 141297
Pennsylvania 119280
Name: 面積, dtype: int64
這些操作方法可以幫助我們更好地理解和分析資料。
資料索引與操作
在 Pandas 中,資料索引是一個非常重要的功能,尤其是在 DataFrame 中。除了使用標籤索引(label-based indexing)外,Pandas 也提供了陣列式索引(array-style indexing)的功能。這種功能是透過 loc 和 iloc 索引器來實作的。
使用 iloc 索引器
iloc 索引器允許我們以陣列式的方式索引 DataFrame,類別似於 NumPy 陣列的索引方式。以下是使用 iloc 索引器的範例:
import pandas as pd
# 建立一個 DataFrame
data = pd.DataFrame({
'area': [423967, 695662, 170312],
'pop': [39538223, 29145505, 21538187]
}, index=['California', 'Texas', 'Florida'])
# 使用 iloc 累加器索引前三行和前兩列
print(data.iloc[:3, :2])
輸出結果:
area pop
California 423967 39538223
Texas 695662 29145505
Florida 170312 21538187
使用 loc 索引器
loc 索引器則允許我們以標籤式的方式索引 DataFrame,但也可以使用陣列式的索引方式。以下是使用 loc 索引器的範例:
# 使用 loc 累加器索引從 'Florida' 到 'pop' 的資料
print(data.loc[:'Florida', :'pop'])
輸出結果:
area pop
California 423967 39538223
Texas 695662 29145505
Florida 170312 21538187
資料操作
Pandas 也提供了多種方式來操作資料,包括設定和修改值。以下是使用 loc 索引器來設定和修改值的範例:
# 設定第一行第三列的值為 90
data.iloc[0, 2] = 90
print(data)
輸出結果:
area pop density
California 423967 39538223 90.0
Texas 695662 29145505 NaN
Florida 170312 21538187 NaN
資料篩選
Pandas 也提供了多種方式來篩選資料,包括使用遮罩(masking)和複雜索引(fancy indexing)。以下是使用 loc 索引器來篩選資料的範例:
# 篩選密度大於 120 的資料
print(data.loc[data['density'] > 120, ['pop', 'density']])
輸出結果:
pop density
Florida 21538187 126.463121
New York 20201249 142.970120
這些範例展示了 Pandas 中資料索引和操作的多種方式,包括使用 iloc 和 loc 索引器,以及設定和修改值、篩選資料等。
資料操作與索引
在 Pandas 中,資料操作和索引是兩個非常重要的概念。資料操作包括了對資料進行篩選、排序、分組等操作,而索引則是用來存取資料的方法。
資料索引
Pandas 中的資料索引可以分為兩種:列索引(column indexing)和行索引(row indexing)。列索引是用來存取資料中的列,而行索引是用來存取資料中的行。
import pandas as pd
# 建立一個 DataFrame
data = {'area': [423967, 695662, 170312, 141297, 119280],
'pop': [39538223, 29145505, 21538187, 20201249, 13002700],
'density': [90.000000, 41.896072, 126.463121, 142.970120, 109.009893]}
df = pd.DataFrame(data, index=['California', 'Texas', 'Florida', 'New York', 'Pennsylvania'])
# 列索引
print(df['Florida':'New York'])
# 行索引
print(df[1:3])
資料篩選
Pandas 中的資料篩選可以使用布林遮罩(boolean mask)來實作。布林遮罩是一個布林值的陣列,用來篩選資料。
# 篩選 density 大於 120 的資料
print(df[df['density'] > 120])
資料操作
Pandas 中的資料操作包括了對資料進行基本的算術操作,如加、減、乘、除等。這些操作可以使用 NumPy 的 ufuncs 來實作。
import numpy as np
# 建立一個 DataFrame
df = pd.DataFrame(np.random.rand(5, 3), columns=['A', 'B', 'C'])
# 對資料進行基本的算術操作
print(df + 1)
print(df - 1)
print(df * 2)
print(df / 2)
ufuncs: 索引保留
Pandas 中的 ufuncs 可以保留索引和列標籤。這意味著當你對資料進行操作時,Pandas 會自動保留索引和列標籤。
# 建立一個 DataFrame
df = pd.DataFrame(np.random.rand(5, 3), columns=['A', 'B', 'C'], index=['a', 'b', 'c', 'd', 'e'])
# 對資料進行基本的算術操作
print(df.apply(np.sqrt))
使用 NumPy 的通用函式(ufunc)進行運算
當我們在 Pandas 物件上應用 NumPy 的通用函式(ufunc)時,結果將是另一個 Pandas 物件,並保留原始索引。這使得對資料進行元素級別的運算變得非常方便。
例子:對 Series 運用 np.exp 函式
import pandas as pd
import numpy as np
# 生成一個隨機整數 Series
ser = pd.Series(np.random.randint(0, 10, 4))
print("原始 Series:")
print(ser)
# 對 Series 運用 np.exp 函式
result_ser = np.exp(ser)
print("\n對 Series 運用 np.exp 的結果:")
print(result_ser)
例子:對 DataFrame 運用 np.exp 函式
import pandas as pd
import numpy as np
# 生成一個隨機整數 DataFrame
df = pd.DataFrame(np.random.randint(0, 10, (3, 4)), columns=['A', 'B', 'C', 'D'])
print("原始 DataFrame:")
print(df)
# 對 DataFrame 運用 np.exp 函式
result_df = np.exp(df)
print("\n對 DataFrame 運用 np.exp 的結果:")
print(result_df)
在這些例子中,np.exp 函式被應用於 Pandas 的 Series 和 DataFrame 物件。結果是新的 Pandas 物件,其中每個元素都是原始元素的指數。這些結果保留了原始物件的索引,對於後續的資料分析非常有用。
使用 Pandas 進行資料操作和索引對齊
Pandas 是一個強大的 Python 函式庫,提供了高效的資料結構和資料分析工具。在本文中,我們將探討如何使用 Pandas 進行資料操作和索引對齊。
基本資料操作
Pandas 提供了多種基本資料操作,包括加、減、乘、除等。這些操作可以直接應用於 Series 或 DataFrame 物件。例如,假設我們有兩個 Series 物件 area 和 population,我們可以計算人口密度如下:
import pandas as pd
# 定義面積和人口資料
area = pd.Series({'Alaska': 1723337, 'Texas': 695662, 'California': 423967}, name='area')
population = pd.Series({'California': 39538223, 'Texas': 29145505, 'Florida': 21538187}, name='population')
# 計算人口密度
population_density = population / area
print(population_density)
輸出結果如下:
Alaska NaN
California 93.257784
Florida NaN
Texas 41.896072
dtype: float64
索引對齊
在進行資料操作時,Pandas 會自動對齊索引。如果兩個 Series 或 DataFrame 物件的索引不完全相同,Pandas 會建立一個新的索引,該索引是兩個原始索引的聯合。任何缺失的值都會被標記為 NaN(Not a Number)。
例如,假設我們有兩個 Series 物件 A 和 B,其索引不同:
A = pd.Series([2, 4, 6], index=[0, 1, 2])
B = pd.Series([1, 3, 5], index=[1, 2, 3])
如果我們將 A 和 B 相加,Pandas 會建立一個新的索引,該索引是兩個原始索引的聯合:
result = A + B
print(result)
輸出結果如下:
0 NaN
1 5.0
2 9.0
3 NaN
dtype: float64
Plantuml 圖表:索引對齊過程
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title Pandas資料選擇操作索引技巧
package "Pandas 資料處理" {
package "資料結構" {
component [Series
一維陣列] as series
component [DataFrame
二維表格] as df
component [Index
索引] as index
}
package "資料操作" {
component [選取 Selection] as select
component [篩選 Filtering] as filter
component [分組 GroupBy] as group
component [合併 Merge/Join] as merge
}
package "資料轉換" {
component [重塑 Reshape] as reshape
component [透視表 Pivot] as pivot
component [聚合 Aggregation] as agg
}
}
series --> df : 組成
index --> df : 索引
df --> select : loc/iloc
df --> filter : 布林索引
df --> group : 分組運算
group --> agg : 聚合函數
df --> merge : 合併資料
df --> reshape : melt/stack
reshape --> pivot : 重新組織
note right of df
核心資料結構
類似 Excel 表格
end note
@enduml
圖表翻譯:索引對齊過程
上述 Plantuml 圖表展示了索引對齊過程。首先,Pandas 將兩個 Series 物件 A 和 B 的索引進行對齊,建立一個新的聯合索引。然後,Pandas 根據聯合索引計算結果,並標記缺失值為 NaN。最終,Pandas 輸出結果,包括聯合索引和計算結果。
從效能最佳化視角來看,Pandas 的 DataFrame 提供了高效的資料存取和操作方法,例如 loc、iloc 和向量化運算,可以顯著提升資料處理速度。然而,需要注意的是,過度使用鏈式索引(chained indexing)可能會導致效能下降,並產生 SettingWithCopyWarning 警告。深入分析 Pandas 的底層實作可以發現,它根據 NumPy 構建,因此利用 NumPy 的通用函式(ufuncs)進行向量化運算能最大程度發揮其效能優勢。同時,理解索引對齊機制對於避免資料操作錯誤至關重要,尤其是在處理不同索引的 DataFrame 或 Series 時,需要關注 NaN 值的產生和處理。對於追求極致效能的應用場景,可以考慮使用其他工具,例如 Dask 或 Vaex,它們可以處理更大規模的資料集。玄貓認為,熟練掌握 Pandas 的資料操作技巧,並結合 NumPy 等工具,能有效提升資料分析效率,是資料科學家必備的技能。