pandas是python中常用的數據分析庫,出現頻率非常高,而且pandas功能之多讓人咋舌,即使pandas老手也沒法保證能高效使用pandas做數據分析。
這篇文章目的梳理幾個高效實用的pandas小技巧,供大家參考。
1. 從剪切板中創建DataFramepandas中的read_clipboard()方法非常神奇,可以把剪切板中的數據變成dataframe格式,也就是說直接在excel中複製表格,可以快速轉化為dataframe。
以下面這個excel數據表為例,全部選中,按ctrl+c複製:
然後在python中執行pd.read_clipboard(),就能得到一模一樣的dataframe數據表:
pd.read_clipboard()這功能對經常在excel和python中切換的分析師來說簡直是福音,excel中的數據能一鍵轉化為pandas可讀格式。
2. 通過數據類型選擇columns數據分析過程可能會需要篩選數據列,比如只需要數值列,以經典的泰坦尼克數據集為例:
import seaborn as sns
# 導出泰坦尼克數據集
df = sns.load_dataset('titanic')
df.head()查看該數據集各列的數據類型:
df.dtypes可以看到各列的數據類型不太一樣,有int、object、float、bool等。
如果說我只要需要數值列,也就是數據類型為int、float的列,可以通過select_dtypes方法實現:
df.select_dtypes(include='number').head()選擇除數據類型為int外其他的列,注意這裡的參數是exclude:
df.select_dtypes(exclude='int').head()也可以選擇多種數據類型:
df.select_dtypes(include=['int', 'datetime', 'object']).head()
3. 將strings改為numbers在pandas中,有兩種方法可以將字符串改為數值:
先創建一個樣本dataframe,看看這兩種方法有什麼不同。
import pandas as pd
df = pd.DataFrame({ 'product': ['A','B','C','D'],
'price': ['10','20','30','40'],
'sales': ['20','-','60','-']
})
dfproduct列是字符串類型,price、sales列雖然內容有數字,但它們的數據類型也是字符串。
值得注意的是,price列都是數字,sales列有數字,但空值用-代替了。
df.dtypes下面我們用astype()方法將price列的數據類型改為int:
df['price'] = df['price'].astype(int)
# 或者用另一種方式
df = df.astype({'price': 'int'})但如果你同樣用astype()方法更改sales列的話就會出現報錯:
df['sales'] = df['sales'].astype(int)原因是sales列裡面的內容除了數字外還有-,它是字符串,沒辦法轉化為int。
而to_numeric()方法卻可以解決這一問題,只需要設置參數errors='coerce'。
df['sales'] = pd.to_numeric(df['sales'], errors='coerce')
df現在sale列中的-已經被替換成了NaN,它的數據類型也變成了float。
df.dtypes
4. 檢測並處理缺失值有一種比較通用的檢測缺失值的方法是info(),它可以統計每列非缺失值的數量。
還是用泰坦尼克數據集:
import seaborn as sns
# 導出泰坦尼克數據集
df = sns.load_dataset('titanic')
df.info()標紅色地方是有缺失值的列,並且給出了非缺失值的數量,你可以計算出該列有多少缺失值。
這樣看可能不夠直觀,那可以用df.isnull().sum()方法很清楚地得到每列有多少缺失值:
df.isnull().sum()df.isnull().sum().sum()則能夠返回該數據集總共有多少缺失值:
df.isnull().sum().sum()還可以看缺失值在該列的佔比是多少,用df.isna().mean()方法:
df.isna().mean()注意:這裡isnull()和isna()使用效果一樣。
那如何處理缺失值呢?
兩種方式:刪除和替換。
df.dropna(axis = 0)df.dropna(axis = 1)df.dropna(thresh=len(df)*0.9, axis=1)df.fillna(value=10)df.fillna(axis=0, method='ffill')df.fillna(axis=1, method='ffill')df.fillna(axis=0, method='bfill')df.fillna(axis=1, method='bfill')df['Age'].fillna(value=df['Age'].mean(), inplace=True)當然你還可以用最大最小值、分位數值等來替換缺失值。
5. 對連續數據進行離散化處理在數據準備過程中,常常會組合或者轉換現有特徵以創建一個新的特徵,其中將連續數據離散化是非常重要的特徵轉化方式,也就是將數值變成類別特徵。
同樣以泰坦尼克數據集為例,裡面有一列是年齡特徵age:
import seaborn as sns
# 導出泰坦尼克數據集
df = sns.load_dataset('titanic')
df['age'].head()年齡是一段連續值,如果我們想對它進行分組變成分類特徵,比如(<=12,兒童)、(<=18,青少年)、(<=60,成人)、(>60,老人),可以用cut方法實現:
import sys
df['ageGroup']=pd.cut(
df['age'],
bins=[0, 13, 19, 61, sys.maxsize],
labels=['兒童', '青少年', '成人', '老人']
)
df.head()注意:這裡的sys.maxsize是指可以存儲的最大值。
可以看到新增了一列ageGroup,用以展示年齡分組:
df['ageGroup'].head()
6. 從多個文件中構建一個DataFrame有時候數據集可能分布在多個excel或者csv文件中,但需要把它讀取到一個DataFrame中,這樣的需求該如何實現?
做法是分別讀取這些文件,然後將多個dataframe組合到一起,變成一個dataframe。
這裡使用內置的glob模塊,來獲取文件路徑,簡潔且更有效率。
在上圖中,glob()在指定目錄中查找所有以「 data_row_」開頭的CSV文件。
glob()以任意順序返回文件名,這就是為什麼使用sort()函數對列表進行排序的原因。
「行合併」
假設數據集按行分布在2個文件中,分別是data_row_1.csv和data_row_2.csv
用以下方法可以逐行合併:
files = sorted(glob('data/data_row_*.csv'))
pd.concat((pd.read_csv(file) for file in files), ignore_index=True)sorted(glob('data/data_row_*.csv'))返回文件名,然後逐個讀取,並且使用concat()方法進行合併,得到結果:
「列合併」
假設數據集按列分布在2個文件中,分別是data_row_1.csv和data_row_2.csv
用以下方法可以逐列合併:
files = sorted(glob('data/data_col_*.csv'))
pd.concat((pd.read_csv(file) for file in files), axis=1)sorted(glob('data/data_row_*.csv'))返回文件名,然後逐個讀取,並且使用concat()方法進行列合併(注意這裡axis=1),得到結果:
本文就到這裡,pandas還有很多讓人驚喜的小技巧,大家有興趣也可以在評論區說說你的使用心得。