作者:Shiu-TangLi
翻譯:吳振東
校對:王雨桐
本文約1800字,建議閱讀6分鐘。
本文為你介紹Pandas隱藏的炫酷小技巧,我相信這些會對你有所幫助。
或許本文中的某些命令你早已知曉,只是沒意識到它還有這種打開方式。
Pandas是一個在Python中廣泛應用的數據分析包。市面上有很多關於Pandas的經典教程,但本文介紹幾個隱藏的炫酷小技巧,我相信這些會對你有所幫助。
1. read_csv
這是讀取數據的入門級命令。當要你所讀取的數據量特別大時,試著加上這個參數 nrows = 5,就可以在載入全部數據前先讀取一小部分數據。如此一來,就可以避免選錯分隔符這樣的錯誤啦(數據不一定都是用逗號來分隔)。
(或者在linux系統中,你可以使用『head』來展示任意文本文件的前五行:head -c 5 data.txt)
接下來,用 df.columns.tolist() 可以提取每一列並轉換成list。還可以加上 usecols = [『c1』, 『c2』, … ]來載入所需要的指定列。另外,如果你知道某些列的類型,你可以加上dtype = {『c1』: str, 『c2』: int, …} ,這樣會加快載入的速度。加入這些參數的另一大好處是,如果這一列中同時含有字符串和數值類型,而你提前聲明把這一列看作是字符串,那麼這一列作為主鍵來融合多個表時,就不會報錯了。
2. select_dtypes
如果已經在Python中完成了數據的預處理,這個命令可以幫你節省一定的時間。在讀取了表格之後,每一列的默認數據類型將會是bool,int64,float64,object,category,timedelta64,或者datetime64。首先你可以觀察一下大致情況,使用:
來了解你的dataframe的每項數據類型,然後再使用:
df.select_dtypes(include=['float64', 'int64'])獲取一個僅由數值類型組成的sub-dataframe。
3. copy
如果你沒聽說過它的話,我不得強調它的重要性。輸入下面的命令:
import pandas as pddf1 = pd.DataFrame({ 'a':[0,0,0], 'b': [1,1,1]})df2 = df1df2['a'] = df2['a'] + 1df1.head()你會發現df1已經發生了改變。這是因為df2 = df1並不是生成一個df1的複製品並把它賦值給df2,而是設定一個指向df1的指針。所以只要是針對df2的改變,也會相應地作用在df1上。為了解決這個問題,你既可以這樣做:
也可以這樣做:
from copy import deepcopydf2 = deepcopy(df1)4. map
這個炫酷的命令讓你的數據轉換變得輕鬆。首先定義一個
dictionary,「key」是轉換前的舊值,而「values」是轉換後的新值。
level_map = {1: 'high', 2: 'medium', 3: 'low'}df['c_level'] = df['c'].map(level_map)幾個適用情景:把True、False,轉換成1、0(為了建模);定義級別;使用字典編碼。
5. 用不用apply?
如果我們想在現有幾列的基礎上生成一個新列,並一同作為輸入,那麼有時apply函數會相當有幫助。
def rule(x, y): if x == 'high' and y > 10: return 1 else: return 0df = pd.DataFrame({ 'c1':[ 'high' ,'high', 'low', 'low'], 'c2': [0, 23, 17, 4]})df['new'] = df.apply(lambda x: rule(x['c1'], x['c2']), axis = 1)df.head()在上面的代碼中,我們定義了一個有兩個輸入變量的函數,並依靠apply函數使其作用到列「c1」和「c2」上。
但是apply函數在有些情況下實在是太慢了。如果你是想計算「c1」和「c2」列的最大值,你當然可以這樣去做:
df['maximum'] = df.apply(lambda x: max(x['c1'], x['c2']), axis = 1)但你會發現相比於以下命令,apply實在是慢太多了:
df['maximum'] = df[['c1','c2']].max(axis =1)結論:如果你可以採用其他內置函數(他們一般速度更快),請不要使用apply。比如說,如果你想把「c」列的值近似取整,那麼請用round(df[『c』], 0)或df['c'],round(0)而不是上文的apply函數。
7. value counts
這個命令用於檢查值的分布。你想要檢查下「c」列中出現的值以及每個值所出現的頻率,可以使用:
下面是一些有用的小技巧/參數:
normalize = True:查看每個值出現的頻率而不是頻次數。
dropna = False: 把缺失值也保留在這次統計中。
sort = False: 將數據按照值來排序而不是按照出現次數排序。
df[『c].value_counts().reset_index(): 將這個統計錶轉換成pandas的dataframe並且進行處理。
8. 缺失值的數量
當構建模型時,我們可能會去除包含過多缺失值或是全部是缺失值的行。這時可以使用.isnull()和.sum()來計算指定列缺失值的數量。
import pandas as pdimport numpy as npdf = pd.DataFrame({ 'id': [1,2,3], 'c1':[0,0,np.nan], 'c2': [np.nan,1,1]})df = df[['id', 'c1', 'c2']]df['num_nulls'] = df[['c1', 'c2']].isnull().sum(axis=1)df.head()9. 依據指定ID來選取行
在SQL中我們可以使用 SELECT * FROM … WHERE ID in (『A001』,『C022』, …)來獲取含有指定ID的記錄。如果你也想在Pandas中做類似的事情,你可以使用:
df_filter = df['ID'].isin(['A001','C022',...])df[df_filter]10. 基於分位數分組
面對一列數值,你想將這一列的值進行分組,比如說最前面的5%放入組別一,5-20%放入組別二,20%-50%放入組別三,最後的50%放入組別四。當然,你可以使用pandas.cut,但你也可以使用下面這種選擇:
import numpy as npcut_points = [np.percentile(df['c'], i) for i in [50, 80, 95]]df['group'] = 1for i in range(3): df['group'] = df['group'] + (df['c'] < cut_points[i])# or <= cut_points[i]這種方法的運行速度很快(並沒有使用到apply函數)。
11. to_csv
這又是一個大家都會用的命令。我想在這裡列出兩個小技巧。首先是
你可以使用這個命令列印出將要輸出文件中的前五行記錄。
另一個技巧是用來處理整數值和缺失值混淆在一起的情況。如果一列含有缺失值和整數值,那麼這一列的數據類型會變成float而不是int。當導出表格時,你可以加上float_format=『%.0f』以便將所有的浮點數近似成整數。當你想把所有列的輸出值都變成整數格式時,就可以使用這個技巧,這樣一來你就會告別所有數值後帶「.0」的煩惱。
原文標題:
10 PythonPandas tricks that make your work more efficient
原文連結:
https://towardsdatascience.com/10-python-pandas-tricks-that-make-your-work-more-efficient-2e8e483808ba
校對:林亦霖
吳振東,法國洛林大學計算機與決策專業碩士。現從事人工智慧和大數據相關工作,以成為數據科學家為終生奮鬥目標。來自山東濟南,不會開挖掘機,但寫得了Java、Python和PPT。
工作內容:需要一顆細緻的心,將選取好的外文文章翻譯成流暢的中文。如果你是數據科學/統計學/計算機類的留學生,或在海外從事相關工作,或對自己外語水平有信心的朋友歡迎加入翻譯小組。
你能得到:定期的翻譯培訓提高志願者的翻譯水平,提高對於數據科學前沿的認知,海外的朋友可以和國內技術應用發展保持聯繫,THU數據派產學研的背景為志願者帶來好的發展機遇。
其他福利:來自於名企的數據科學工作者,北大清華以及海外等名校學生他們都將成為你在翻譯小組的夥伴。
點擊文末「閱讀原文」加入數據派團隊~
轉載須知
如需轉載,請在開篇顯著位置註明作者和出處(轉自:數據派ID:datapi),並在文章結尾放置數據派醒目二維碼。有原創標識文章,請發送【文章名稱-待授權公眾號名稱及ID】至聯繫郵箱,申請白名單授權並按要求編輯。
發布後請將連結反饋至聯繫郵箱(見下方)。未經許可的轉載以及改編者,我們將依法追究其法律責任。
點擊「閱讀原文」擁抱組織