在資料分析的叢林中,資料清理如同披荊斬棘,是確保資料品質的關鍵步驟。Pandas 提供了強大的工具,如同鋒利的刀刃,能有效處理缺失值和重複資料,讓資料分析師得以在乾淨的資料上建立可靠的分析結果。本文將探討 dropna()
和 drop_duplicates()
方法的應用,並分享一些實戰技巧與最佳實務。
移除缺失值:dropna() 的精妙應用
dropna()
方法如同資料的篩子,可以精準地篩除 DataFrame 中包含缺失值(NaN)的行或列。預設情況下,dropna()
會移除任何包含至少一個 NaN 的整行資料。
import pandas as pd
df = pd.DataFrame([['cold','slow', None, 2.7, 6.6, 3.1],
['warm', 'medium', 4.2, 5.1, 7.9, 9.1],
['hot', 'fast', 9.4, 11.0, None, 6.8],
['cool', None, None, None, 9.1, 8.9],
['cool', 'medium', 6.1, 4.3, 12.2, 3.7],
[None, 'slow', None, 2.9, 3.3, 1.7],
[None, 'slow', None, 2.9, 3.3, 1.7]],
columns=['Temp', 'Speed', 'Measure1', 'Measure2', 'Measure3', 'Measure4'])
df_dropped = df.dropna()
print(df_dropped)
這段程式碼首先構建了一個包含缺失值的 DataFrame,如同一個佈滿陷阱的資料池。接著,dropna()
方法就像一個過濾網,將包含 NaN 的行撈除,並將乾淨的資料儲存到新的 DataFrame df_dropped
中。最後,印出 df_dropped
,只會顯示不包含任何 NaN 的行,也就是索引為 1 和 4 的兩行資料,如同從陷阱中篩選出的寶藏。
dropna()
也支援 inplace=True
引數,可以直接修改原始 DataFrame,無需建立新的 DataFrame,如同在資料池中直接清除陷阱。
df.dropna(inplace=True)
print(df)
此處使用 inplace=True
引數,dropna()
方法會直接修改原始的 df
DataFrame。執行後,df
中所有包含 NaN 的行都會被刪除,如同直接在資料池中進行清理。
除了刪除行,dropna()
也可以刪除包含 NaN 的列,只需設定 axis=1
引數即可,如同調整過濾網的方向。
df = pd.DataFrame([['cold','slow', None, 2.7, 6.6, 3.1],
['warm', 'medium', 4.2, 5.1, 7.9, 9.1],
['hot', 'fast', 9.4, 11.0, None, 6.8],
['cool', None, None, None, 9.1, 8.9],
['cool', 'medium', 6.1, 4.3, 12.2, 3.7],
[None, 'slow', None, 2.9, 3.3, 1.7],
[None, 'slow', None, 2.9, 3.3, 1.7]],
columns=['Temp', 'Speed', 'Measure1', 'Measure2', 'Measure3', 'Measure4'])
df.dropna(axis=1, inplace=True)
print(df)
設定 axis=1
後,dropna()
會沿著列的方向搜尋 NaN,如同改變了篩選的方向。在此範例中,任何包含 NaN 的列都會被刪除,就像將資料池中垂直方向的陷阱清除。
使用 thresh 引數:更精細的資料保留策略
dropna()
的 thresh
引數可以設定保留行的最低非缺失值數量,如同設定一個資料池的最低水位線。例如,thresh=4
表示只有至少包含 4 個非缺失值的列才會被保留。
df = pd.DataFrame([['cold','slow', None, 2.7, 6.6, 3.1],
['warm', 'medium', 4.2, 5.1, 7.9, 9.1],
['hot', 'fast', 9.4, 11.0, None, 6.8],
['cool', None, None, None, 9.1, 8.9],
['cool', 'medium', 6.1, 4.3, 12.2, 3.7],
[None, 'slow', None, 2.9, 3.3, 1.7],
[None, 'slow', None, 2.9, 3.3, 1.7]],
columns=['Temp', 'Speed', 'Measure1', 'Measure2', 'Measure3', 'Measure4'])
df_thresh = df.dropna(thresh=4)
print(df_thresh)
這裡設定 thresh=4
,dropna()
方法會保留至少有 4 個非 NaN 值的行。 如同設定了水位線,只有水位線以上的資料會被保留。
graph LR A[載入 DataFrame] --> B{檢查缺失值?} B --|有缺失值| C[使用 dropna()] C --> D[刪除包含 NaN 的行] C --> E[刪除包含 NaN 的列] C --> F[刪除非 NaN 值少於 n 的行] B --|無缺失值| G[繼續分析] D --> G E --> G F --> G
透過 dropna()
方法的靈活運用,我們可以有效地清除資料中的缺失值,為後續的資料分析奠定堅實的基礎。
持續更新中… (這句話必須移除)
Python 與 SAS 的資料格式轉換之道
身為一個在資料科學領域打滾多年的技術工作者,玄貓經常需要在 Python 和 SAS 之間切換。兩種語言各有千秋,但資料格式的差異有時會造成些許不便。因此,我整理了一些 Python 和 SAS 資料格式轉換的技巧,希望能幫助大家更順暢地運用這兩種工具。
整數格式的顯示控制
Python 和 SAS 預設顯示整數的方式略有不同。以下是如何控制整數顯示格式的技巧:
Python:前導零與正號
在 Python 中,可以使用格式化字串或 f-string 來控制整數的顯示方式。例如,要顯示帶有前導零的整數,可以使用 {:04d}
的格式:
number = 99
formatted_number = f"{number:04d}" # 或 '{:04d}'.format(number)
print(formatted_number) # 輸出 0099
04d
表示使用 4 位數字顯示整數,不足 4 位則用 0 填充。d
代表十進位整數。
要顯示帶有前導正號的整數,可以使用 {:+d}
或 {:+04d}
的格式:
number = 99
formatted_number = f"{number:+d}" # 或 '{:+04d}'.format(number)
print(formatted_number) # 輸出 +99
+d
表示顯示帶有正號的整數。
SAS:前導零與正號
在 SAS 中,可以使用 z
格式來顯示帶前導零的整數,使用 FORMAT
陳述式定義格式:
data _null_;
int = 99;
put int z4.; /* 輸出 0099 */
run;
z4.
格式表示使用 4 位數字顯示整數,不足 4 位則用 0 填充。
要顯示帶前導正號的整數,可以自定義一個 picture 格式:
proc format;
picture plussign low-high = ' 00' (prefix='+'); /* 定義格式 */
run;
data _null_;
int = 99;
put int plussign.; /* 輸出 +99 */
run;
picture
陳述式定義了一個名為 plussign
的格式,prefix='+'
表示在數字前加上正號。
浮點數格式的顯示控制
Python:控制小數位數與百分比格式
Python 中,使用 f-string 可以輕鬆控制浮點數的小數位數:
pi = 3.14159265
formatted_pi = f"{pi:.2f}" # 或 '{:.2f}'.format(pi)
print(formatted_pi) # 輸出 3.14
.2f
表示顯示小數點後兩位。
要顯示百分比格式,可以使用 .2%
:
ratio = 0.0422
formatted_ratio = f"{ratio:.2%}" # 或 '{:.2%}'.format(ratio)
print(formatted_ratio) # 輸出 4.22%
.2%
表示將數字乘以 100 後,顯示小數點後兩位,並加上百分號。
SAS:百分比格式
SAS 中,使用 percent
格式顯示百分比:
data _null_;
pct = 0.0422;
put pct percent8.2; /* 輸出 4.22% */
run;
percent8.2
格式表示顯示百分比,總長度為 8,小數點後兩位。
日期時間格式處理
Python:日期時間處理
Python 的 datetime
模組提供了強大的日期時間處理功能。以下是如何使用 strftime()
格式化日期時間的示例:
from datetime import datetime
now = datetime.now()
formatted_date = now.strftime("%Y-%m-%d") # 格式化為 YYYY-MM-DD
formatted_time = now.strftime("%H:%M:%S") # 格式化為 HH:MM:SS
print(formatted_date)
print(formatted_time)
strftime()
方法可以根據指定的格式字串格式化日期時間。%Y
代表年份,%m
代表月份,%d
代表日期,%H
代表小時,%M
代表分鐘,%S
代表秒。
SAS:日期時間處理
SAS 也提供了豐富的日期時間函式和格式。以下是如何在 SAS 中格式化日期時間的示例:
data _null_;
now = datetime();
formatted_date = put(datepart(now), yymmdd10.); /* 格式化為 YYYY-MM-DD */
formatted_time = put(timepart(now), time8.); /* 格式化為 HH:MM:SS */
put formatted_date;
put formatted_time;
run;
datetime()
函式傳回當前的日期時間。datepart()
函式提取日期部分,timepart()
函式提取時間部分。yymmdd10.
和 time8.
是 SAS 提供的日期和時間格式。
graph LR C[C] A[日期時間資料] --> B{Python - datetime} A --> C{SAS - 日期時間函式}
圖表説明: 此圖表説明 Python 和 SAS 都能處理日期時間資料,Python 使用 datetime
模組,SAS 使用內建的日期時間函式。
透過這些技巧,我們可以更有效地在 Python 和 SAS 之間轉換資料,並根據需要調整資料格式,以滿足不同的分析需求。
從亂數生成探索 Python 與 SAS 的資料處理差異
在資料分析領域,Python 和 SAS 都是不可或缺的工具。瞭解它們在資料處理上的差異,有助於我們更有效地選擇和使用這些工具。本文將以亂數生成為例,比較 Python 和 SAS 在資料處理方面的特性。
動態型別 vs. 靜態型別
Python 是一種動態型別語言,變數型別在指定時自動確定。SAS 則是一種靜態型別語言,需要事先宣告變數型別。
Python:使用 numpy 和 pandas 生成亂數
import numpy as np
import pandas as pd
np.random.seed(12345) # 設定亂數種子
random_numbers = pd.Series(np.random.randn(10)) # 生成 10 個標準常態分佈亂數
print(random_numbers)
numpy
函式庫提供高效的數值計算功能,pandas
函式庫提供資料分析工具。np.random.seed()
設定亂數種子,確保結果可重複。pd.Series()
建立一個 pandas Series 物件,用於儲存亂數。
SAS:生成亂數
data _null_;
call streaminit(12345); /* 設定亂數種子 */
do i = 1 to 10;
x = rand("Normal"); /* 生成標準常態分佈亂數 */
put x;
end;
run;
call streaminit()
設定亂數種子。rand("Normal")
函式生成標準常態分佈亂數。
pandas:Python 資料分析的利器
pandas 函式庫是 Python 資料分析的核心工具,提供 Series
和 DataFrame
等高效的資料結構。
graph LR A[Python - pandas] --> B(Series) A --> C(DataFrame)
圖表説明: pandas 提供 Series
(一維) 和 DataFrame
(二維) 資料結構,方便資料處理和分析。
Series
類別似於 SAS 中的變數,DataFrame
類別似於 SAS 資料集。pandas 提供豐富的資料操作功能,例如資料清洗、轉換、聚合等,使其成為 Python 資料分析的利器。
透過以上示例,我們可以看出 Python 和 SAS 在資料處理方面各有優勢。Python 的動態型別和 pandas 函式庫使其更加靈活易用,而 SAS 的靜態型別和嚴謹的語法使其更適合大型專案。選擇哪種工具取決於具體的分析需求和個人偏好。
Python 的日期與時間處理:從 datetime 模組到 pandas 資料型別
在資料分析領域,日期和時間資料的處理至關重要。Python 提供了 datetime
模組和 pandas
函式庫,為我們提供了強大的工具來處理這類別資料。datetime
模組定義了日期、時間和日期時間物件,而 pandas
則以其高效的資料結構和函式,簡化了日期時間資料的操作。不同於 SAS 使用數值表示日期時間,Python 以物件的形式儲存,更貼近我們對日期和時間的理解。
Pandas 資料型別:資料科學家的工具箱
pandas
函式庫建立在 NumPy 基礎之上,不僅繼承了 NumPy 的資料型別,也定義了許多專屬的資料型別,例如 datetime64
和 timedelta
,專門用於處理日期時間資料。以下表格列出常用的 pandas
資料型別:
Pandas 資料型別 | Python 資料型別 | 用途 |
---|---|---|
object | str | 文字序列 |
int64 | int | 整數 |
float64 | float | 浮點數 |
bool | bool | 布林值 (True/False) |
datetime64 | - | 日期和時間值 |
timedelta | - | 兩個日期時間的差值 |
category | - | 類別變數 |
這些資料型別如同資料科學家的工具箱,讓我們能更有效地處理和分析不同型別的資料。object
類別型類別似於 SAS 的字元變數,用於處理字串值。int64
和 float64
分別對應 SAS 的數值型別,用於儲存整數和浮點數。
Pandas 資料結構:Series 與 DataFrame
Pandas 提供了兩種主要的資料結構:Series 和 DataFrame。Series 是一維的標籤化陣列,可以儲存任何資料型別。DataFrame 則是一個二維的表格型資料結構,由多個 Series 組成,分享相同的索引。
資料的序列
Series 就像一列火車,每個車廂都裝載著一個資料值,而車廂的編號就是索引。
import pandas as pd
import numpy as np
# 使用預設索引
s1 = pd.Series(np.random.randn(5))
print(s1)
# 使用自定義索引
s2 = pd.Series(np.random.randn(10), index=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])
print(s2)
這段程式碼首先匯入了 pandas
和 numpy
兩個函式庫。接著,使用 pd.Series()
建立了兩個 Series:s1
使用預設的數值索引,而 s2
則使用自定義的字母索引。np.random.randn()
用於生成隨機數。
print(s2[0]) # 使用預設數值索引
print(s2['a']) # 使用自定義索引
print(s2[:3]) # 切片,取得前三個元素
print(s2[:'c']) # 切片,取得索引'c'之前的元素
這段程式碼展示瞭如何使用索引和切片來取得 Series 中的元素。可以使用數值索引或自定義索引,切片則可以取得一段範圍內的元素。
DataFrame:資料的表格
DataFrame 就像一個資料表格,由多個 Series 組成。
# 從 CSV 檔案讀取資料
df = pd.read_csv("https://raw.githubusercontent.com/RandyBetancourt/PythonForSASUsers/master/data/uk_accidents.csv")
print(df.shape) # 顯示 DataFrame 的形狀 (列數, 欄數)
這段程式碼使用 pd.read_csv()
從指定的 URL 讀取 CSV 檔案,並建立一個 DataFrame。df.shape
屬性可以顯示 DataFrame 的列數和欄數。
graph LR subgraph DataFrame A[欄位 1] --> B(索引) C[欄位 2] --> B D[欄位 3] --> B E[...] --> B end
這個圖表展示了 DataFrame 的基本結構:多個欄位分享同一個索引。
print(df.info()) # 顯示 DataFrame 的資訊
df.info()
方法可以顯示 DataFrame 的詳細資訊,包括欄位名稱、資料型別、非空值數量、記憶體使用量等。
深入 DataFrame:資料檢視與探索
RangeIndex:DataFrame 的預設索引
DataFrame 預設使用 RangeIndex 作為行索引,類別似 SAS 的 _N_
。我們也可以使用 set_index()
方法設定其他欄位作為索引。
# 建立 DataFrame 時指定索引
df = pd.read_csv('d:\\data\\Customers.csv', index_col=['Last_Name', 'First_Name'])
# 建立後修改索引
df = df.set_index('Customer_ID')
資料型別:info()
與 dtype
info()
方法提供 DataFrame 的資訊概覽,包含資料型別。dtype
屬性則顯示特定欄位的資料型別。
df.info()
print(df['Date'].dtype)
df = pd.read_csv("C:\\Data\\uk_accidents.csv", parse_dates=['Date'])
資料檢視:head()
、tail()
與 describe()
head()
和 tail()
方法分別顯示 DataFrame 的前幾行和後幾行資料。describe()
方法提供數值型欄位的描述性統計資訊。
print(df.tail(10))
print(df.head(5))
print(df.describe())
graph LR D[D] A[DataFrame] --> B(head) A --> C(tail) A --> D{describe}
資料切片:[[ ]]
運算元
[[ ]]
運算元可以根據欄位標籤選取特定欄位。
print(df[['Sex_of_Driver', 'Time']].head(10))
視覺化探索:直方圖
import matplotlib.pyplot as plt
df.hist(column='Sex_of_Driver', grid=False)
plt.show()
這段程式碼使用 matplotlib.pyplot
函式庫繪製 ‘Sex_of_Driver’ 欄位的直方圖,幫助我們理解資料分佈。
處理 Pandas 缺失值:None 與 NaN
Pandas 使用 None
和 NaN
表示缺失值。None
通常用於物件型態,而 NaN
用於數值型態。
import pandas as pd
df1 = pd.DataFrame([['cold', 9],
['warm', 4],
[None , 4]],
columns=['Strings', 'Integers'])
print(df1)
print(df1.dtypes)
df1.loc[df1.Integers == 9, 'Integers'] = None
print(df1)
print(df1.dtypes)
內容解密
這段程式碼示範了 None
和 NaN
的使用。當在整數欄中使用 None
時,Pandas 會自動將該欄的資料型別轉換為浮點數,以容納 NaN
。
本文探討了 Pandas 的資料型別、資料結構以及處理缺失值的方法,並結合程式碼示例和圖表説明,希望能幫助讀者更好地理解和應用 Pandas 進行資料分析。
import pandas as pd
# 建立範例 DataFrame
data = {'col1': [1, 2, 3, 2, 1], 'col2': [4, 5, 6, 5, 4]}
df = pd.DataFrame(data, index=[0, 1, 2, 3, 4])
# 顯示原始 DataFrame
print("原始 DataFrame:\n", df)
# 使用 drop_duplicates() 刪除重複列
df_no_duplicates = df.drop_duplicates()
# 顯示刪除重複列後的 DataFrame
print("\n刪除重複列後的 DataFrame:\n", df_no_duplicates)
# 建立包含缺失值的 DataFrame
data_with_nan = {'col1': [1, 2, None, 2, 1], 'col2': [4, 5, 6, None, 4]}
df_with_nan = pd.DataFrame(data_with_nan, index=[0, 1, 2, 3, 4])
print("\n包含缺失值的 DataFrame:\n",df_with_nan)
# 使用 dropna() 刪除包含缺失值的列
df_no_nan = df_with_nan.dropna()
print("\n刪除包含缺失值的列後的 DataFrame:\n",df_no_nan)
這段程式碼示範瞭如何使用 Pandas 刪除 DataFrame 中的重複列和處理缺失值。首先,我們建立一個包含重複列的 DataFrame,並使用 drop_duplicates()
方法刪除重複項。接著,我們建立另一個包含缺失值(NaN)的 DataFrame,並使用 dropna()
方法刪除包含 NaN 的列。
graph LR A["建立 DataFrame"] --> B{"包含缺失值?"} B -- "Yes" --> C["使用 dropna() 刪除缺失值"] B -- "No" --> D{"包含重複資料?"} D -- "Yes" --> E["使用 drop_duplicates() 刪除重複資料"] D -- "No" --> F["資料清理完成"] C --> F E --> F
這張流程圖清晰地展現了資料清理的步驟:首先檢查 DataFrame 是否包含缺失值,若有則使用 dropna()
處理;接著檢查是否包含重複資料,若有則使用 drop_duplicates()
處理。最後,完成資料清理。
Pandas 提供了強大的資料清理功能,drop_duplicates()
和 dropna()
是其中兩個非常實用的工具。drop_duplicates()
可以根據所有欄位或指定欄位刪除重複列,而 dropna()
可以刪除包含任何缺失值或指定欄位缺失值的列。 根據實際需求選擇不同的引數和方法,可以更精確地控制資料清理的過程。