2024-07-31|閱讀時間 ‧ 約 26 分鐘

【資料分析】Pandas 基礎操作語法彙整

raw-image

pandas是用於資料操縱和分析的Python軟體庫。它建造在 NumPy 基礎上,並為操縱數值表格和時間序列,提供了資料結構和運算操作。

pandas 提供了高效且靈活的數據結構和數據操作工具,主要包括 SeriesDataFrame 兩種數據結構。Series 是一維標籤數組,而 DataFrame 是二維的表格數據結構,類似於 Excel 表格。

Pandas 將 Python 打造成一個強大的資料處理工具,讓資料科學家和分析師能夠快速地對數據進行清洗、分析和可視化,從而提高工作效率並做出數據驅動的決策。


# 可使用目錄功能快速確認要閱覽的主題


Pandas 資料基礎操作語法

import pandas as pd

### 創健一個範例資料集 ###
data = pd.DataFrame({
'col1': [1, 2, 3, 4],
'col2': [5, 6, 7, 8],
'col3': [9, 10, 11, 12]
'name': ['Jerry','Tom','Bob','Amy']
})


資料查看

# 查看該資料集的前五筆資料
data.head()

# 查看該資料集的前八筆資料
data.head(8)

# 查看該資料集的後五筆資料
data.tail()

# 查看該資料集的後八筆資料
data.tail(8)

# 查看該資料的形狀
data.shape

# 查看該資料集的描述性統計信息和數據摘要
data.describe()

# 查看該資料集的結構性摘要信息
data.info()

# 查看該資料集的dtype屬性
data.dtypes​

# 查看所有欄位中最大的值
data.max()

# 指定 age 欄位,查看該欄位最大的值​
data['age'].max()

# 計算指定資料中,每個類別或數值出現的次數​
titanic["Pclass"].value_counts()

# 以 Pclass 做分組,計算每個類別或數值出現的次數​
titanic.groupby("Pclass")["Pclass"].count()

# 在 data 中,object 類型的欄位,計算每欄出現的唯一值的數量
data.select_dtypes(["object"]).nunique()


資料選擇

# 選擇第一列資料
row = data.loc[0]

# 選擇第一列和第二列資料
rows = data.loc[[0, 1]]

# 選擇第一列和第二列,以及第一欄和第二欄的資料
subset = data.loc[[0, 1], ['col1', 'col2']]

# ':'表示所有行,​'col2':'col3'表示'col2'到'col3'的所有列
subset2 = data.loc[:,'col2':'col3']

# loc 方法可以按照標籤選擇資料,而 iloc 方法可以按照索引位置選擇資料。
# ​選擇第 10 行到第 25 行(不含第 25 行)的數據,以及第 3 列到第 5 列(不含第 5 列)的數據。
titanic.iloc[9:25, 2:5]

# 將特定 Column 定義為 index
# 選取 "Jerry" 和 "Amy" 兩筆資料的 "col2" 和 "col3" 這兩個欄位
data.set_index('name', inplace=True)
result = df.loc[['Jerry', 'Amy'], ['col2', 'col3']]
result

# 選擇 col1 的所有資料(Series)
data['col1']

# 選擇 col1、col3 的所有資料(Dataframe)
data[['col1','col3']]

# ​選擇前三列的所有資料(Dataframe)
data[0:3]

# 將特定 Column 定義為 index ,利用 Row 名稱進行選取
data.set_index('name', inplace=True)
data['Jerry':'Bob']

# 刪除特定欄位
data = data.drop('欄位名稱', axis=1)

# 刪除多個欄位
data = data.drop(['欄位名稱1', '欄位名稱2'], axis=1)

# 使用 inplace=True 直接修改原始 DataFrame
data.drop('欄位名稱', axis=1, inplace=True)


資料過濾

# 選擇 col1 大於 10 的資料
subset = data.query('col1 > 10')

# 選擇 col1 大於 10 且 col2 小於 20 的資料
subset = data[(data['col1'] > 10) & (data['col2'] < 20)]

# 使用多個條件組合過濾資料
mask = (data['col2'] > 7) & (data['name'] == 'Tom')
data[mask]

# ​以鐵達尼號資料為例,選擇 Pclass 欄位中,Pclass 等於 2 跟 3 的所有資料
class_23 = titanic[titanic["Pclass"].isin([2, 3])]

# ​以鐵達尼號資料為例,選擇 age 欄位中沒有缺失值的所有資料
age_no_na = titanic[titanic["Age"].notna()]


資料排序

# 按照 col1 排序,預設為升序排序(從小到大)
data.sort_values('col1')

# 按照 col1 和 col2 排序
data.sort_values(['col1', 'col2'])

# 按照 col1 升序排列,col2 降序排列(從大到小)
data.sort_values(['col1', 'col2'], ascending=[True, False])

# 按照索引進行排序
data.sort_index()

# ​按照 Age 來排序,預設為升序排序(從小到大)
titanic.sort_values(by="Age")

# ​先按照 Pclass 來排序,在按照 Age 來排序,並指定以降序排序(從大到小)
titanic.sort_values(by=['Pclass', 'Age'], ascending=False)


資料去重

# 去除重複資料
data.drop_duplicates()


資料計算

import pandas as pd

# 計算​ titanic 資料中的 Age 平均值
titanic["Age"].mean()

# 計算 ​titanic 資料中的 Age 以及 Fare 的中位數
titanic[["Age", "Fare"]].median()

# 創建兩個DataFrame物件
data1 = {'name': ['Alice', 'Bob', 'Charlie', 'David'],
'age': [25, 32, 18, 47],
'city': ['New York', 'Paris', 'London', 'Berlin']}
df1 = pd.DataFrame(data1)

data2 = {'name': ['Eva', 'Frank', 'Grace', 'Henry'],
'age': [29, 23, 37, 31],
'city': ['Rome', 'Sydney', 'Tokyo', 'Moscow']}
df2 = pd.DataFrame(data2)

# 進行加法
print(df1 + df2)

"""
name age city
0 AliceEva 54 New YorkRome
1 BobFrank 55 ParisSydney
2 CharlieGrace 55 LondonTokyo
3 DavidHenry 78 BerlinMoscow
"""

# 按照 "city" 的值進行分組,並對每個城市的人口數、平均年齡、平均薪資進行統計分析
grouped = df.groupby('city')
result = grouped.agg({'name': 'count', 'age': 'mean', 'salary': 'mean'})
print(result)

"""
name age salary
city
Berlin 1 47.000000 100000.000000
London 1 18.000000 25000.000000
New York 2 24.000000 42500.000000
Paris 2 31.500000 77500.000000
"""

# 對鐵達尼號資料,選擇 Sex 和 Age 列,以 Sex 作為分組做平均,回傳 DataFram
​titanic[["Sex", "Age"]].groupby("Sex").mean()

"""​
Age
Sex
female 27.915709
male 30.726645
"""

# ​對鐵達尼號資料,以 Sex 為分組,只針對數值資料做平均
titanic.groupby("Sex").mean(numeric_only=True)

# ​對鐵達尼號資料,以 Sex 為分組,做 Age 的平均,回傳 series
titanic.groupby("Sex")["Age"].mean()

# ​對鐵達尼號資料,以 Sex 和 Pclass 為分組,做 Fare 的平均,回傳 series
​titanic.groupby(["Sex", "Pclass"])["Fare"].mean()


增加、刪除資料欄位

# 創建​一個新欄位,資料為 col1 欄位的數值*2 
data["新增欄位名"] = data["col1"] * 2

# 創建​一個新欄位,計算 col1 與 col2 的比率
data["投資報酬率"] = (data["投資淨損益"] / data["投入資金"])

# 使用 loc 新增一行
dfta.loc[2] = ['第一欄位內容', '第二欄位內容']

# 新增一列並且想保持原有 DataFrame 不變,使用 assign 新增一列
data = pd.DataFrame({ 'Name': ['Alice', 'Bob'], 'Age': [25, 30] })
data_new = data.assign(City=['New York', 'Los Angeles'])

# 刪除特定欄位 'Column_Name'
data = data.drop(columns=['Column_Name'])

# 刪除特定行(根據索引)
data = data.drop(index=[0]) # 刪除第0行

# 如果要一次刪除多行
data = data.drop(index=[0, 1]) # 刪除第0和第1行

# 刪除特定欄位 'Column_Name',直接在原 DataFrame 上修改
data.drop(columns=['Column_Name'], inplace=True)


資料合併與重組(concat)

使用 concat() 方法可以將多個DataFrame物件沿著指定的軸合併在一起。

import pandas as pd

# 創建兩個DataFrame物件
data1 = {'name': ['Alice', 'Bob', 'Charlie', 'David'],
'age': [25, 32, 18, 47],
'city': ['New York', 'Paris', 'London', 'Berlin']}
df1 = pd.DataFrame(data1)

data2 = {'name': ['Eva', 'Frank', 'Grace', 'Henry'],
'age': [29, 23, 37, 31],
'city': ['Rome', 'Sydney', 'Tokyo', 'Moscow']}
df2 = pd.DataFrame(data2)

# 沿著上下合併
print(pd.concat([df1, df2], axis=0))

"""
name age city
0 Alice 25 New York
1 Bob 32 Paris
2 Charlie 18 London
3 David 47 Berlin
0 Eva 29 Rome
1 Frank 23 Sydney
2 Grace 37 Tokyo
3 Henry 31 Moscow
"""

# 沿著左右合併
print(pd.concat([df1, df2], axis=1))

"""
name age city name age city
0 Alice 25 New York Eva 29 Rome
1 Bob 32 Paris Frank 23 Sydney
2 Charlie 18 London Grace 37 Tokyo
3 David 47 Berlin Henry 31 Moscow
"""

# 合併兩個DataFrame後,增加一層索引,方便辨識資料來自哪一個資料集
pd.concat([df1,df2],keys=['data1','data2'])

"""
name age city
data1 0 Alice 25 New York
1 Bob 32 Paris
2 Charlie 18 London
3 David 47 Berlin
data2 0 Eva 29 Rome
1 Frank 23 Sydney
2 Grace 37 Tokyo
3 Henry 31 Moscow
"""



資料合併與重組(merge)

使用 merge() 方法可以根據指定的欄位將兩個DataFrame物件合併在一起。

import pandas as pd

# 創建兩個DataFrame物件
data1 = {'name': ['Alice', 'Bob', 'Charlie', 'David'],
'age': [25, 32, 18, 47],
'city': ['New York', 'Paris', 'London', 'Berlin']}
df1 = pd.DataFrame(data1)

data2 = {'name': ['Alice', 'Bob', 'Charlie', 'David'],
'salary': [5000, 6000, 7000, 8000]}
df2 = pd.DataFrame(data2)

# 根據name欄位合併,若兩個 DataFrame 沒有匹配到相同 name,則不會合併
print(pd.merge(df1, df2, on='name'))


"""
name age city salary
0 Alice 25 New York 5000
1 Bob 32 Paris 6000
2 Charlie 18 London 7000
3 David 47 Berlin 8000
"""

# 根據name欄位合併, 所有 df1 資料都會被保留
# 若 df1 跟 df2 有無匹配到的資料,合併後的空欄位會顯示 NaN
print(pd.merge(df1, df2, how='left', on='name'))


資料合併與重組(merge) (續)

import pandas as pd

data1 = {'employee_id': [1, 2, 3, 4],
         'name': ['Alice', 'Bob', 'Charlie', 'David']}
df1 = pd.DataFrame(data1)

data2 = {'id': [1, 2, 3, 4],
         'salary': [5000, 6000, 7000, 8000]}
df2 = pd.DataFrame(data2)

# 當​欲合併的兩個 DataFrame 有列名稱不同,但內容相同的情況
# ​使用 left_on 和 right_on 來指定需要對齊的列。
merged_df = pd.merge(df1, df2, left_on='employee_id', right_on='id')
merged_df

"""
employee_id name id salary
0 1 Alice 1 5000
1 2 Bob 2 6000
2 3 Charlie 3 7000
3 4 David 4 8000
"""
import pandas as pd

data1 = {'first_name': ['Alice', 'Bob', 'Charlie', 'David'],
'last_name': ['Smith', 'Brown', 'Johnson', 'Williams'],
'age': [25, 32, 18, 47]}
df1 = pd.DataFrame(data1)

data2 = {'fname': ['Alice', 'Bob', 'Charlie', 'David'],
'lname': ['Smith', 'Brown', 'Johnson', 'Williams'],
'salary': [5000, 6000, 7000, 8000]}
df2 = pd.DataFrame(data2)

# ​通過指定 left_on 和 right_on 來正確地合併這兩個DataFrame。
merged_df = pd.merge(df1, df2, left_on=['first_name', 'last_name'], right_on=['fname', 'lname'])
merged_df

"""
first_name last_name age fname lname salary
0 Alice Smith 25 Alice Smith 5000
1 Bob Brown 32 Bob Brown 6000
2 Charlie Johnson 18 Charlie Johnson 7000
3 David Williams 47 David Williams 8000
"""


資料合併與重組(join)

使用 join() 方法可以將兩個DataFrame物件按照索引合併在一起。

import pandas as pd

# 創建兩個DataFrame物件
data1 = {'age': [25, 32, 18, 47],
'city': ['New York', 'Paris', 'London', 'Berlin']}
df1 = pd.DataFrame(data1, index=['Alice', 'Bob', 'Charlie', 'David'])

data2 = {'salary': [5000, 6000, 7000, 8000]}
df2 = pd.DataFrame(data2, index=['Alice', 'Bob', 'Charlie', 'David'])

# 按照索引合併
print(df1.join(df2))

"""
age city salary
Alice 25 New York 5000
Bob 32 Paris 6000
Charlie 18 London 7000
David 47 Berlin 8000
"""


分組資料處理(groupby)

使用 groupby() 方法可以將 DataFrame 分組後對每個組進行操作。

import pandas as pd

data = {'name': ['Alice', 'Bob', 'Charlie', 'David', 'Emma', 'Frank'],
'age': [25, 32, 18, 47, 23, 31],
'gender': ['female', 'male', 'female', 'male', 'female', 'male'],
'city': ['New York', 'Paris', 'London', 'Berlin', 'New York', 'Paris'],
'salary': [50000, 80000, 25000, 100000, 35000, 75000]}
df = pd.DataFrame(data)


# 按照 "city" 的值進行分組,並對每個城市的人口數、平均年齡、平均薪資進行統計分析
grouped = df.groupby('city')
result = grouped.agg({'name': 'count', 'age': 'mean', 'salary': 'mean'})
print(result)

"""
name age salary
city
Berlin 1 47.000000 100000.000000
London 1 18.000000 25000.000000
New York 2 24.000000 42500.000000
Paris 2 31.500000 77500.000000
"""

# 對鐵達尼號資料,選擇 Sex 和 Age 列,以 Sex 作為分組做平均,回傳 DataFram
​titanic[["Sex", "Age"]].groupby("Sex").mean()

"""​
Age
Sex
female 27.915709
male 30.726645
"""

# ​對鐵達尼號資料,以 Sex 為分組,只針對數值資料做平均
titanic.groupby("Sex").mean(numeric_only=True)

# ​對鐵達尼號資料,以 Sex 為分組,做 Age 的平均,回傳 series
titanic.groupby("Sex")["Age"].mean()

# ​對鐵達尼號資料,以 Sex 和 Pclass 為分組,做 Fare 的平均,回傳 series
​titanic.groupby(["Sex", "Pclass"])["Fare"].mean()

# 對鐵達尼號資料,以 Pclass 做分組,計算每個類別或數值出現的次數​
titanic.groupby("Pclass")["Pclass"].count()

# 對鐵達尼號資料,以 Sex 做分組,做 Age 的平均,返回一個與原始 DataFrame 大小相同的 series
titanic.groupby("Sex")["Age"].transform("mean")


資料匯入與匯出

import pandas as pd

# 匯入csv檔​(DataFrame)
titanic = pd.read_csv("data/titanic.csv")

# 將資料匯出為excel​
titanic.to_excel("titanic.xlsx", sheet_name="passengers", index=False)


資料 columns 更名

# 更改 columns 名稱,使用字典,鍵為原名,值為更改後的名
​air_quality_renamed = air_quality.rename(
...: columns={
...: "station_antwerp": "BETR801",
...: "station_paris": "FR04014",
...: "station_london": "London Westminster",
...: }
...: )

# ​將 columns 名稱全部更改微小寫
air_quality_renamed = air_quality_renamed.rename(columns=str.lower)


其它常用指令

待補

分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.