返回文章列表

Pandas資料選擇操作索引技巧

本文深入探討 Pandas 的資料選擇、操作與索引技巧,包含使用 loc、iloc 進行資料存取、修改、篩選,以及運用 NumPy 的通用函式進行運算,並詳細說明索引對齊的機制,幫助讀者更有效率地處理和分析資料。

資料科學 Python

Pandas 提供了多種便捷的資料操作方式,其中 lociloc 是兩種重要的索引器,允許我們以標籤或位置索引資料。理解這兩種索引器的差異和用法,對於有效地操作 DataFrame 至關重要。此外,Pandas 支援使用 NumPy 的通用函式,可以直接對 DataFrame 進行元素級運算,並保留索引,方便後續分析。在進行不同 DataFrame 或 Series 之間的運算時,Pandas 會自動進行索引對齊,確保運算的正確性,但需要注意缺失值的處理。熟練掌握這些技巧,能大幅提升資料處理效率。

資料選擇在 DataFrame 中

Python 的一個重要原則是「明確比隱含好」。這種明確的性質使得 lociloc 在維護乾淨和可讀的程式碼時非常有用,特別是在整數索引的情況下,使用它們可以防止由混合索引/切片約定引起的隱藏 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:areapop,分別代表各州的面積和人口資料。然後,我們建立了一個 DataFrame data,其中包含了這兩個 Series 作為欄位。最後,我們列印預出 DataFrame 的內容。

這種方法展示瞭如何將 DataFrame 視為一組相關的 Series 物件的字典,並如何透過字典風格的索引來存取個別的 Series。這種方法在資料分析和處理中非常有用,因為它允許我們以更直觀和方便的方式選擇和操作資料。

圖表翻譯:

在這個圖表中,我們展示了 DataFrame 和 Series 之間的關係。DataFrame 包含多個 Series,每個 Series 都代表了一個欄位(在這個例子中是面積和人口)。每個 Series 都儲存了相應的資料(各州的面積和人口資料)。這種結構使得資料選擇和操作變得更加方便和直觀。

使用 Pandas DataFrame 進行資料操作

當我們處理資料時,經常需要存取和操作資料中的特定欄位。Pandas 的 DataFrame 提供了多種方法來實作這一功能。

存取欄位

假設我們有一個 DataFrame data,其中包含多個欄位,包括 areapop。我們可以使用以下方法存取這些欄位:

# 使用字典式存取
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)

圖表翻譯

內容解密

上述範例程式碼建立了一個包含 areapop 欄位的 DataFrame,然後增加了一個新的 density 欄位,其值為 pop 欄位除以 area 欄位。這個過程展示瞭如何使用 Pandas DataFrame 進行資料操作和新增欄位。

資料分析與操作

在進行資料分析時,瞭解資料的結構和內容是非常重要的。以下將展示如何使用 Pandas 進行資料操作和分析。

資料預覽

首先,我們可以預覽資料的內容。假設我們有一個 DataFrame,包含了美國各州的面積、人口和人口密度等資訊。

州名面積人口人口密度
California4239673953822393.257784
Texas6956622914550541.896072
Florida17031221538187126.463121
New York14129720201249142.970120
Pennsylvania11928013002700109.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)的功能。這種功能是透過 lociloc 索引器來實作的。

使用 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 中資料索引和操作的多種方式,包括使用 ilocloc 索引器,以及設定和修改值、篩選資料等。

資料操作與索引

在 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 物件 areapopulation,我們可以計算人口密度如下:

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 物件 AB,其索引不同:

A = pd.Series([2, 4, 6], index=[0, 1, 2])
B = pd.Series([1, 3, 5], index=[1, 2, 3])

如果我們將 AB 相加,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 物件 AB 的索引進行對齊,建立一個新的聯合索引。然後,Pandas 根據聯合索引計算結果,並標記缺失值為 NaN。最終,Pandas 輸出結果,包括聯合索引和計算結果。

從效能最佳化視角來看,Pandas 的 DataFrame 提供了高效的資料存取和操作方法,例如 lociloc 和向量化運算,可以顯著提升資料處理速度。然而,需要注意的是,過度使用鏈式索引(chained indexing)可能會導致效能下降,並產生 SettingWithCopyWarning 警告。深入分析 Pandas 的底層實作可以發現,它根據 NumPy 構建,因此利用 NumPy 的通用函式(ufuncs)進行向量化運算能最大程度發揮其效能優勢。同時,理解索引對齊機制對於避免資料操作錯誤至關重要,尤其是在處理不同索引的 DataFrame 或 Series 時,需要關注 NaN 值的產生和處理。對於追求極致效能的應用場景,可以考慮使用其他工具,例如 Dask 或 Vaex,它們可以處理更大規模的資料集。玄貓認為,熟練掌握 Pandas 的資料操作技巧,並結合 NumPy 等工具,能有效提升資料分析效率,是資料科學家必備的技能。