import seaborn as sns
import pandas as pd
import numpy as np
Pandas Indexing and Selecting
讓我們來討論一下pandas數據的切片和切分(slicing and dicing),類似于R里面的數據框或矩陣取子集氧秘。今天我們將復習四個主題:
- 復習基礎知識
- 多重索引
- 獲取單個值
- 一些不用在意的東西
關于基礎知識可以參考: basic indexing ,索引相關可參考 advanced indexing. 但要這些資料會很冗長趴久,他會提供一些你可能都用不到的方法丸相,或者沒有必要掌握的技能,自行選擇:
復習基礎知識
首先朋鞍,讓我們簡單回顧一下傳統(tǒng)的索引和篩選(indexing and selection)已添。(我們在pandas基礎知識pandas fundamentals中介紹了大部分內容)。首先滥酥,以下是我們將要使用的數據(舊的 tips 數據):
這個數據存放在:https://github.com/guipsamora/pandas_exercises/tree/master/07_Visualization/Tips
ls
?[31mCombining DataFrames.ipynb?[m?[m* ?[31mPandas Intro to Data Structures.ipynb?[m?[m*
?[31mGroup Operations.ipynb?[m?[m* ?[31mRow-Column Transformations.ipynb?[m?[m*
?[31mIndexing and Selecting.ipynb?[m?[m* ?[31mtips.csv?[m?[m*
?[31mMisc Functions.ipynb?[m?[m*
tips = pd.read_csv('tips.csv')
tips.head()
del tips['Unnamed: 0']
tips.head(3)
下面介紹4種方式從數據框中獲取數據:
- 獲取不同的列
# 1) get columns
tips[['total_bill', 'tip']].head()
- 獲取不同的行
# 2) get some rows
tips[3:5]
- 根據行名列名獲取數據
# 3) select rows and columns based on their name
tips.loc[2:4, 'sex': 'smoker']
- 根據位置信息獲取數據
# 4) select rows and columns by their ordering
tips.iloc[1:3, 0:2]
- 根據邏輯值來篩選
# 5) select using a bool series
tips[tips['tip'] > 1].head()
不過這些僅僅是冰山一角更舞。
實際上,當你深入研究pandas的其他功能(functionalities)時坎吻,你很可能會涉及到其他幾個重要的概念缆蝉。
Multi-index
這是一個您可能認為不需要的主題--但事實證明它是一個相當頻繁的用例(usecase)。
multi-index
背后的最初想法是提供一個框架來處理更高的模糊數據(從而取代panels
)瘦真。
但由于一些操作刊头,這變得相當平常。在幾乎所有情況下诸尽,multi-index都來自groupby's(您幾乎不會自己構建或閱讀它)原杂。
下面我們舉個例子:
tips.head()
mi_tips = tips.groupby(['sex', 'smoker']).agg({'tip': 'mean'})
mi_tips
mi_tips.index
MultiIndex([('Female', 'No'),
('Female', 'Yes'),
( 'Male', 'No'),
( 'Male', 'Yes')],
names=['sex', 'smoker'])
最終,您可以在此類型的數據之上執(zhí)行大量操作您机。您還可以執(zhí)行等效的multi-index操作穿肄,如下所示:
mi_tips.loc[('Male', 'No')]
tip 3.113402
Name: (Male, No), dtype: float64
通過這種方式,你會學到很多細節(jié)际看,但是總會有例外咸产。
因此,我一直以來處理這個問題的方法很簡單仲闽,就是重置索引脑溢。
ri_tips = mi_tips.reset_index()
ri_tips
請注意我們現(xiàn)在是如何將值分布到整個column中的。因此赖欣,通過這種方式屑彻,很容易只選擇不吸煙的男性(the male non-smokers):
ri_tips[(ri_tips['smoker'] == 'No') & (ri_tips['sex'] == 'Male')]
處理此問題的另一種方法是只刪除某些索引:
ri0_tips = mi_tips.reset_index(level=0)
ri0_tips.loc['Yes']
然后如果再需要用到之前的索引验庙,還可以換回來,參考pull indexes back into the index (通常這個操作使用在某些類型數據合并的過程中)酱酬。
ri_tips.set_index(['sex', 'smoker'])
ri0_tips.set_index('sex', append=True)
獲取單個值
下一個索引小把戲(indexing trick)主要是關于速度的壶谒。它是在獲取和設置單一的值(使用后提升計算速度)。這是一個非常簡單的問題:
tips.head(3)
當需要獲取/設定單個值要用到at
函數
tips.at[0, 'total_bill'] = 9000
tips.head(3)
tips.iat[0, 0]
9000.0
如果您正在修改數據框的單個值膳沽,則應該始終使用這些工具汗菜。它速度更快,而且是知道您沒有搞砸的好方法(經常修改數據可能會導致奇怪的錯誤)挑社。
所以陨界,為了證明它更快,我們來計時吧痛阻!
%%timeit
tips.at[0, 'total_bill'] = 6
6.12 μs ± 46.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%%timeit
tips.loc['total_bill', 0] = 6
272 μs ± 4.49 μs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
看上去at的速度比較快菌瘪。
Where, Masks and Queries
這些都是pandas內置的東西,我個人從來沒有用過阱当,主要是因為它們相當多余俏扩,而且不經常發(fā)生。
他們的速度要快一點弊添。但是感覺可能不值得這樣做录淡。所以,如果你想學油坝,就去學吧(文檔在here)嫉戚。如果不是,可能就無關緊要了澈圈。
下面讓我向您展示如何復制mask功能彬檀。
df = pd.DataFrame(np.random.randn(25).reshape((5, 5)))
df.head()
df.where(df > 0)
df[df < 0] = np.NaN
df
小結
這就是我所知道的關于索引的全部內容,并探索所有您需要知道的內容瞬女。
如果您有任何問題或意見窍帝,請在我的簡書留言!
附:在這方面沒有什么特別好的教程诽偷,如果你知道有更多更好的坤学,請在留言給我一個教程的鏈接,感謝渤刃!
同步更新于我的個人微信公眾號: