從剪貼板中創(chuàng)建DataFrame 假設(shè)你將一些數(shù)據(jù)儲存在Excel或者Google Sheet中,你又想要盡快地將他們讀取至DataFrame中。
和read_csv()類似,read_clipboard()會自動檢測每一列的正確的數(shù)據(jù)類型: 讓我們再復(fù)制另外一個數(shù)據(jù)至剪貼板: 神奇的是,pandas已經(jīng)將第一列作為索引了: 需要注意的是,如果你想要你的工作在未來可復(fù)制,那么read_clipboard()并不值得推薦。 將DataFrame劃分為兩個隨機(jī)的子集 假設(shè)你想要將一個DataFrame劃分為兩部分,隨機(jī)地將75%的行給一個DataFrame,剩下的25%的行給另一個DataFrame。
我們可以使用sample()函數(shù)來隨機(jī)選取75%的行,并將它們賦值給'movies_1'DataFrame: 接著我們使用drop()函數(shù)來舍棄“moive_1”中出現(xiàn)過的行,將剩下的行賦值給'movies_2'DataFrame: 你可以發(fā)現(xiàn)總的行數(shù)是正確的: 你還可以檢查每部電影的索引,或者'moives_1': 或者'moives_2': 需要注意的是,這個方法在索引值不唯一的情況下不起作用。
讓我們先看一眼movies這個DataFrame:In [60]: movies.head()
Out[60]: 其中有一列是genre(類型): 比如我們想要對該DataFrame進(jìn)行過濾,我們只想顯示genre為Action或者Drama或者Western的電影,我們可以使用多個條件,以'or'符號分隔:
但是,你實際上可以使用isin()函數(shù)將代碼寫得更加清晰,將genres列表傳遞給該函數(shù): In [63]: movies[movies.genre.isin(['Action', 'Drama', 'Western'])].head()
Out[63]: 如果你想要進(jìn)行相反的過濾,也就是你將吧剛才的三種類型的電影排除掉,那么你可以在過濾條件前加上破浪號:
這種方法能夠起作用是因為在Python中,波浪號表示“not”操作。 假設(shè)你想要對movies這個DataFrame通過genre進(jìn)行過濾,但是只需要前3個數(shù)量最多的genre。 我們對genre使用value_counts()函數(shù),并將它保存成counts(type為Series): 該Series的nlargest()函數(shù)能夠輕松地計算出Series中前3個最大值: 事實上我們在該Series中需要的是索引: 最后,我們將該索引傳遞給isin()函數(shù),該函數(shù)會把它當(dāng)成genre列表: In [68]: movies[movies.genre.isin(counts.nlargest(3).index)].head()
Out[68]: 這樣,在DataFrame中只剩下Drame, Comdey, Action這三種類型的電影了。 讓我們來看一看UFO sightings這個DataFrame: 你將會注意到有些值是缺失的。
isna()會產(chǎn)生一個由True和False組成的DataFrame,sum()會將所有的True值轉(zhuǎn)換為1,F(xiàn)alse轉(zhuǎn)換為0并把它們加起來。 類似地,你可以通過mean()和isna()函數(shù)找出每一列中缺失值的百分比。 如果你想要舍棄那些包含了缺失值的列,你可以使用dropna()函數(shù): 或者你想要舍棄那么缺失值占比超過10%的列,你可以給dropna()設(shè)置一個閾值: len(ufo)返回總行數(shù),我們將它乘以0.9,以告訴pandas保留那些至少90%的值不是缺失值的列。 我們先創(chuàng)建另一個新的示例DataFrame: 如果我們需要將“name”這一列劃分為三個獨立的列,用來表示first, middle, last name呢?我們將會使用str.split()函數(shù),告訴它以空格進(jìn)行分隔,并將結(jié)果擴(kuò)展成一個DataFrame: 這三列實際上可以通過一行代碼保存至原來的DataFrame: 如果我們想要劃分一個字符串,但是僅保留其中一個結(jié)果列呢?比如說,讓我們以', '來劃分location這一列: 如果我們只想保留第0列作為city name,我們僅需要選擇那一列并保存至DataFrame: 讓我們創(chuàng)建一個新的示例DataFrame: 這里有兩列,第二列包含了Python中的由整數(shù)元素組成的列表。 如果我們想要將第二列擴(kuò)展成DataFrame,我們可以對那一列使用apply()函數(shù)并傳遞給Series constructor: 通過使用concat()函數(shù),我們可以將原來的DataFrame和新的DataFrame組合起來: 讓我們來看一眼從Chipotle restaurant chain得到的orders這個DataFrame:
每個訂單(order)都有訂單號(order_id),包含一行或者多行。為了找出每個訂單的總價格,你可以將那個訂單號的價格(item_price)加起來。比如,這里是訂單號為1的總價格: 如果你想要計算每個訂單的總價格,你可以對order_id使用groupby(),再對每個group的item_price進(jìn)行求和。 但是,事實上你不可能在聚合時僅使用一個函數(shù),比如sum()。為了對多個函數(shù)進(jìn)行聚合,你可以使用agg()函數(shù),傳給它一個函數(shù)列表,比如sum()和count(): 這將告訴我們沒定訂單的總價格和數(shù)量。 讓我們再看一眼orders這個DataFrame: In [86]: orders.head(10)
Out[86]: 如果我們想要增加新的一列,用于展示每個訂單的總價格呢?回憶一下,我們通過使用sum()函數(shù)得到了總價格: sum()是一個聚合函數(shù),這表明它返回輸入數(shù)據(jù)的精簡版本(reduced version )。
比這個函數(shù)的輸入要?。?/span> 解決的辦法是使用transform()函數(shù),它會執(zhí)行相同的操作但是返回與輸入數(shù)據(jù)相同的形狀: 我們將這個結(jié)果存儲至DataFrame中新的一列:
你可以看到,每個訂單的總價格在每一行中顯示出來了。 這樣我們就能方便地甲酸每個訂單的價格占該訂單的總價格的百分比: In [92]: orders['percent_of_total'] = orders.item_price / orders.total_price orders.head(10)
In [92]: 讓我們看一眼另一個數(shù)據(jù)集:
這就是著名的Titanic數(shù)據(jù)集,它保存了Titanic上乘客的信息以及他們是否存活。
但是,這個DataFrame結(jié)果可能比你想要的信息顯示得更多。 如果你想對這個結(jié)果進(jìn)行過濾,只想顯示“五數(shù)概括法”(five-number summary)的信息,你可以使用loc函數(shù)并傳遞'min'到'max'的切片: 如果你不是對所有列都感興趣,你也可以傳遞列名的切片: Titanic數(shù)據(jù)集的Survived列由1和0組成,因此你可以對這一列計算總的存活率: 如果你想對某個類別,比如“Sex”,計算存活率,你可以使用groupby(): 如果你想一次性對兩個類別變量計算存活率,你可以對這些類別變量使用groupby(): 該結(jié)果展示了由Sex和Passenger Class聯(lián)合起來的存活率。它存儲為一個MultiIndexed Series,也就是說它對實際數(shù)據(jù)有多個索引層級。
該DataFrame包含了與MultiIndexed Series一樣的數(shù)據(jù),不同的是,現(xiàn)在你可以用熟悉的DataFrame的函數(shù)對它進(jìn)行操作。 如果你經(jīng)常使用上述的方法創(chuàng)建DataFrames,你也許會發(fā)現(xiàn)用pivot_table()函數(shù)更為便捷: 想要使用數(shù)據(jù)透視表,你需要指定索引(index), 列名(columns), 值(values)和聚合函數(shù)(aggregation function)。
這個結(jié)果既顯示了總的存活率,也顯示了Sex和Passenger Class的存活率。
這個結(jié)果展示了每一對類別變量組合后的記錄總數(shù)。 讓我們來看一下Titanic數(shù)據(jù)集中的Age那一列: 它現(xiàn)在是連續(xù)性數(shù)據(jù),但是如果我們想要將它轉(zhuǎn)變成類別數(shù)據(jù)呢? 一個解決辦法是對年齡范圍打標(biāo)簽,比如'adult', 'young adult', 'child'。實現(xiàn)該功能的最好方式是使用cut()函數(shù): 這會對每個值打上標(biāo)簽。0到18歲的打上標(biāo)簽'child',18-25歲的打上標(biāo)簽'young adult',25到99歲的打上標(biāo)簽“adult”。 注意到,該數(shù)據(jù)類型為類別變量,該類別變量自動排好序了(有序的類別變量)。 上一個技巧在你想要修改整個jupyter notebook中的顯示會很有用。但是,一個更靈活和有用的方法是定義特定DataFrame中的格式化(style)。
我們可以創(chuàng)建一個格式化字符串的字典,用于對每一列進(jìn)行格式化。然后將其傳遞給DataFrame的style.format()函數(shù): 注意到,Date列是month-day-year的格式,Close列包含一個$符號,Volume列包含逗號。
我們現(xiàn)在隱藏了索引,將Close列中的最小值高亮成紅色,將Close列中的最大值高亮成淺綠色。
Volume列現(xiàn)在有一個漸變的背景色,你可以輕松地識別出大的和小的數(shù)值。
現(xiàn)在,Volumn列上有一個條形圖,DataFrame上有一個標(biāo)題。 請注意,還有許多其他的選項你可以用來格式化DataFrame。 Profile a DataFrame假設(shè)你拿到一個新的數(shù)據(jù)集,你不想要花費太多力氣,只是想快速地探索下。那么你可以使用pandas-profiling這個模塊。 在你的系統(tǒng)上安裝好該模塊,然后使用ProfileReport()函數(shù),傳遞的參數(shù)為任何一個DataFrame。它會返回一個互動的HTML報告:
使用示例如下(只顯示第一部分的報告):
來源:博客園 |
|