04Pandas 數(shù)據(jù)處理基礎(chǔ)

數(shù)據(jù)類型

Pandas 的數(shù)據(jù)類型主要有以下幾種,它們分別是:Series(一維數(shù)組)逆屡,DataFrame(二維數(shù)組)前鹅,Panel(三維數(shù)組),Panel4D(四維數(shù)組)既棺,PanelND(更多維數(shù)組)讽挟。其中 Series 和 DataFrame 應(yīng)用的最為廣泛,幾乎占據(jù)了使用頻率 90% 以上丸冕。
Series
其可以儲(chǔ)存整數(shù)耽梅、浮點(diǎn)數(shù)、字符串等類型的數(shù)據(jù)胖烛。Series 基本結(jié)構(gòu)如下:

pandas.Series(data=None, index=None)

data 可以是字典眼姐,或者NumPy 里的 ndarray 對(duì)象等。index 是數(shù)據(jù)索引佩番,索引是 Pandas 數(shù)據(jù)結(jié)構(gòu)中的一大特性众旗,它主要的功能是幫助我們更快速地定位數(shù)據(jù)。
基于 Python 字典新建一個(gè)示例 Series趟畏。

%matplotlib inline
import pandas as pd

s = pd.Series({'a': 10, 'b': 20, 'c': 30})
s

該 Series 的數(shù)據(jù)值是 10, 20, 30贡歧,索引為 a, b, c,數(shù)據(jù)值的類型默認(rèn)識(shí)別為 int64±洌可以通過 type 來確認(rèn) s 的類型律想。

type(s)

Series 則可以基于 NumPy 中的一維數(shù)據(jù)轉(zhuǎn)換。

import numpy as np

s = pd.Series(np.random.randn(5))
s

最終得到的 Series 索引默認(rèn)從 0 開始绍弟,而數(shù)值類型為 float64技即。
DataFrame
DataFrame 是 Pandas 中最為常見、最重要且使用頻率最高的數(shù)據(jù)結(jié)構(gòu)樟遣。DataFrame 和平常的電子表格或 SQL 表結(jié)構(gòu)相似而叼。你可以把 DataFrame 看成是 Series 的擴(kuò)展類型,它仿佛是由多個(gè) Series 拼合而成豹悬。它和 Series 的直觀區(qū)別在于葵陵,數(shù)據(jù)不但具有行索引,且具有列索引瞻佛。

image.png

DataFrame 基本結(jié)構(gòu)如下:

pandas.DataFrame(data=None, index=None, columns=None)

DataFrame 可以由以下多個(gè)類型的數(shù)據(jù)構(gòu)建:
一維數(shù)組埃难、列表、字典或者 Series 字典涤久。
二維或者結(jié)構(gòu)化的 numpy.ndarray涡尘。
一個(gè) Series 或者另一個(gè) DataFrame。

使用一個(gè)由 Series 組成的字典來構(gòu)建 DataFrame响迂。

df = pd.DataFrame({'one': pd.Series([1, 2, 3]),
                   'two': pd.Series([4, 5, 6])})
df

當(dāng)不指定索引時(shí)考抄,DataFrame 的索引同樣是從 0 開始。我們也可以直接通過一個(gè)列表構(gòu)成的字典來生成 DataFrame蔗彤。

df = pd.DataFrame({'one': [1, 2, 3],
                   'two': [4, 5, 6]})
df

由帶字典的列表生成 DataFrame川梅。

df = pd.DataFrame([{'one': 1, 'two': 4},
                   {'one': 2, 'two': 5},
                   {'one': 3, 'two': 6}])
df

NumPy 的多維數(shù)組非常常用,同樣可以基于二維數(shù)值來構(gòu)建一個(gè) DataFrame然遏。

pd.DataFrame(np.random.randint(5, size=(2, 4)))

Series 實(shí)際上可以被初略看出是只有 1 列數(shù)據(jù)的 DataFrame贫途。當(dāng)然,這個(gè)說法不嚴(yán)謹(jǐn)待侵,二者的核心區(qū)別仍然是 Series 沒有列索引丢早。可以觀察如下所示由 NumPy 一維隨機(jī)數(shù)組生成的 Series 和 DataFrame秧倾。

pd.Series(np.random.randint(5, size=(5,)))
pd.DataFrame(np.random.randint(5, size=(5,)))

數(shù)據(jù)讀取

讀取數(shù)據(jù) CSV 文件的方法是 pandas.read_csv()怨酝,可以直接傳入一個(gè)相對(duì)路徑,或者是網(wǎng)絡(luò) URL那先。

df = pd.read_csv("https://labfile.oss.aliyuncs.com/courses/906/los_census.csv")
df

由于 CSV 存儲(chǔ)時(shí)是一個(gè)二維的表格农猬,那么 Pandas 會(huì)自動(dòng)將其讀取為 DataFrame 類型。
pd.read_ 前綴開始的方法還可以讀取各式各樣的數(shù)據(jù)文件售淡,且支持連接數(shù)據(jù)庫斤葱。
因?yàn)?Pandas 針對(duì)數(shù)據(jù)操作的全部方法都是基于 Pandas 支持的數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)的慷垮。也就是說,只有 Series 或者 DataFrame 才能使用 Pandas 提供的方法和函數(shù)進(jìn)行處理揍堕。所以换帜,學(xué)習(xí)真正數(shù)據(jù)處理方法之前,我們需要將數(shù)據(jù)轉(zhuǎn)換生成為 Series 或 DataFrame 類型鹤啡。

基本操作

DataFrame 結(jié)構(gòu)大致由 3 部分組成,它們分別是列名稱蹲嚣、索引和數(shù)據(jù)递瑰。


image.png

有些時(shí)候,我們讀取的文件很大隙畜。如果全部輸出預(yù)覽這些文件抖部,既不美觀,又很耗時(shí)议惰。Pandas 提供了 head() 和 tail() 方法慎颗,它可以幫助我們只預(yù)覽一小塊數(shù)據(jù)。

df.head()  # 默認(rèn)顯示前 5 條
df.tail(7)  # 指定顯示后 7 條

Pandas 還提供了統(tǒng)計(jì)和描述性方法言询,方便你從宏觀的角度去了解數(shù)據(jù)集俯萎。describe() 相當(dāng)于對(duì)數(shù)據(jù)集進(jìn)行概覽,會(huì)輸出該數(shù)據(jù)集每一列數(shù)據(jù)的計(jì)數(shù)运杭、最大值夫啊、最小值等。

df.describe()

Pandas 基于 NumPy 開發(fā)辆憔,所以任何時(shí)候你都可以通過 .values 將 DataFrame 轉(zhuǎn)換為 NumPy 數(shù)組撇眯。

df.values

可以同時(shí)使用 Pandas 和 NumPy 提供的 API 對(duì)同一數(shù)據(jù)進(jìn)行操作,并在二者之間進(jìn)行隨意轉(zhuǎn)換虱咧。

df.index  # 查看索引
df.columns  # 查看列名
df.shape  # 查看形狀

數(shù)據(jù)選擇

在數(shù)據(jù)預(yù)處理過程中熊榛,我們往往會(huì)對(duì)數(shù)據(jù)集進(jìn)行切分,只將需要的某些行腕巡、列玄坦,或者數(shù)據(jù)塊保留下來,輸出到下一個(gè)流程中去绘沉。這也就是所謂的數(shù)據(jù)選擇营搅,或者數(shù)據(jù)索引。
基于索引數(shù)字選擇
當(dāng)我們新建一個(gè) DataFrame 之后梆砸,如果未自己指定行索引或者列對(duì)應(yīng)的標(biāo)簽转质,那么 Pandas 會(huì)默認(rèn)從 0 開始以數(shù)字的形式作為行索引,并以數(shù)據(jù)集的第一行作為列對(duì)應(yīng)的標(biāo)簽帖世。其實(shí)休蟹,這里的「列」也有數(shù)字索引沸枯,默認(rèn)也是從 0 開始,只是未顯示出來赂弓。
我們首先可以基于數(shù)字索引對(duì)數(shù)據(jù)集進(jìn)行選擇绑榴。這里用到的 Pandas 中的 .iloc 方法。該方法可以接受的類型有:
整數(shù)盈魁。例如:5
整數(shù)構(gòu)成的列表或數(shù)組翔怎。例如:[1, 2, 3]
布爾數(shù)組。
可返回索引值的函數(shù)或參數(shù)杨耙。

首先赤套,我們可以選擇前 3 行數(shù)據(jù)。這和 Python 或者 NumPy 里面的切片很相似珊膜。

df.iloc[:3]

我們還可以選擇特定的一行容握。

df.iloc[5]

df.iloc[] 的 [[行],[列]] 里面可以同時(shí)接受行和列的位置车柠,如果你想要選擇 1剔氏,3,5 行竹祷,可以這樣做谈跛。

df.iloc[[1, 3, 5]]

我們要選擇第 2-4 列。

df.iloc[:, 1:4]

這里選擇 2-4 列塑陵,輸入的卻是 1:4币旧。這和 Python 或者 NumPy 里面的切片操作非常相似。既然我們能定位行和列猿妈,那么只需要組合起來吹菱,我們就可以選擇數(shù)據(jù)集中的任何數(shù)據(jù)了。
基于標(biāo)簽名稱選擇
除了根據(jù)數(shù)字索引選擇彭则,還可以直接根據(jù)標(biāo)簽對(duì)應(yīng)的名稱選擇鳍刷。為 df.loc[]
df.loc[] 可以接受的類型有:
單個(gè)標(biāo)簽俯抖。例如:2 或 'a'输瓜,這里的 2 指的是標(biāo)簽而不是索引位置。
列表或數(shù)組包含的標(biāo)簽芬萍。例如:['A', 'B', 'C']尤揣。
切片對(duì)象。例如:'A':'E'柬祠,注意這里和上面切片的不同之處北戏,首尾都包含在內(nèi)。
布爾數(shù)組漫蛔。
可返回標(biāo)簽的函數(shù)或參數(shù)嗜愈。

先選擇前 3 行:

df.loc[0:2]

再選擇 1旧蛾,3,5 行:

df.loc[[0, 2, 4]]

然后蠕嫁,選擇 2-4 列:

df.loc[:, 'Total Population':'Total Males']

最后锨天,選擇 1,3 行和 Median Age 后面的列:

df.loc[[0, 2], 'Median Age':]

數(shù)據(jù)刪減

以 .drop 開頭的方法都與數(shù)據(jù)刪減有關(guān)剃毒。
DataFrame.drop 可以直接去掉數(shù)據(jù)集中指定的列和行病袄。一般在使用時(shí),我們指定 labels 標(biāo)簽參數(shù)赘阀,然后再通過 axis 指定按列或按行刪除即可益缠。當(dāng)然,你也可以通過索引參數(shù)刪除數(shù)據(jù)纤壁,具體查看官方文檔。

df.drop(labels=['Median Age', 'Total Males'], axis=1)

DataFrame.drop_duplicates 則通常用于數(shù)據(jù)去重捺信,即剔除數(shù)據(jù)集中的重復(fù)值酌媒。使用方法非常簡單,指定去除重復(fù)值規(guī)則迄靠,以及 axis 按列還是按行去除即可秒咨。

df.drop_duplicates()

另一個(gè)用于數(shù)據(jù)刪減的方法 DataFrame.dropna 也十分常用,其主要的用途是刪除缺少值掌挚,即數(shù)據(jù)集中空缺的數(shù)據(jù)列或行雨席。

df.dropna()

數(shù)據(jù)填充

在真實(shí)的生產(chǎn)環(huán)境中,我們需要處理的數(shù)據(jù)文件往往沒有想象中的那么美好吠式。其中陡厘,很大幾率會(huì)遇到的情況就是缺失值。缺失值主要是指數(shù)據(jù)丟失的現(xiàn)象特占,也就是數(shù)據(jù)集中的某一塊數(shù)據(jù)不存在糙置。除此之外、存在但明顯不正確的數(shù)據(jù)也被歸為缺失值一類是目。例如谤饭,在一個(gè)時(shí)間序列數(shù)據(jù)集中,某一段數(shù)據(jù)突然發(fā)生了時(shí)間流錯(cuò)亂懊纳,那么這一小塊數(shù)據(jù)就是毫無意義的揉抵,可以被歸為缺失值。
檢測(cè)缺失值
Pandas 為了更方便地檢測(cè)缺失值嗤疯,將不同類型數(shù)據(jù)的缺失均采用 NaN 標(biāo)記冤今。這里的 NaN 代表 Not a Number,它僅僅是作為一個(gè)標(biāo)記茂缚。例外是辟汰,在時(shí)間序列里列敲,時(shí)間戳的丟失采用 NaT 標(biāo)記。
Pandas 中用于檢測(cè)缺失值主要用到兩個(gè)方法帖汞,分別是:isna()notna()戴而,故名思意就是「是缺失值」和「不是缺失值」。默認(rèn)會(huì)返回布爾值用于判斷翩蘸。

df = pd.DataFrame(np.random.rand(9, 5), columns=list('ABCDE'))
# 插入 T 列所意,并打上時(shí)間戳
df.insert(value=pd.Timestamp('2017-10-1'), loc=0, column='Time')
# 將 1, 3, 5 列的 1,3催首,5扶踊,7 行置為缺失值
df.iloc[[1, 3, 5, 7], [0, 2, 4]] = np.nan
# 將 2, 4, 6 列的 2,4郎任,6秧耗,8 行置為缺失值
df.iloc[[2, 4, 6, 8], [1, 3, 5]] = np.nan
df

然后,通過 isna()notna() 中的一個(gè)即可確定數(shù)據(jù)集中的缺失值舶治。

df.isna()

面對(duì)缺失值一般就是填充和剔除兩項(xiàng)操作分井。填充和清除都是兩個(gè)極端。如果你感覺有必要保留缺失值所在的列或行霉猛,那么就需要對(duì)缺失值進(jìn)行填充尺锚。如果沒有必要保留,就可以選擇清除缺失值惜浅。
我們可以用相同的標(biāo)量值替換 NaN瘫辩,比如用 0。

df.fillna(0)

除了直接填充值坛悉,我們還可以通過參數(shù)伐厌,將缺失值前面或者后面的值填充給相應(yīng)的缺失值。例如使用缺失值前面的值進(jìn)行填充:

df.fillna(method='pad')

或者是后面的值:

df.fillna(method='bfill')

如果存在連續(xù)的缺失值是怎樣的情況呢裸影?試一試弧械。首先,我們將數(shù)據(jù)集的第 2空民,4 刃唐,6 列的第 3,5 行也置為缺失值界轩。

df.iloc[[3, 5], [1, 3, 5]] = np.nan

然后來正向填充:

df.fillna(method='pad')

可以看到画饥,連續(xù)缺失值也是按照前序數(shù)值進(jìn)行填充的,并且完全填充浊猾。這里抖甘,我們可以通過 limit= 參數(shù)設(shè)置連續(xù)填充的限制數(shù)量。

df.fillna(method='pad', limit=1)  # 最多填充一項(xiàng)

除了上面的填充方式葫慎,還可以通過 Pandas 自帶的求平均值方法等來填充特定列或行衔彻。

df.fillna(df.mean()['C':'E'])

插值填充
插值是數(shù)值分析中一種方法薇宠。簡而言之,就是借助于一個(gè)函數(shù)(線性或非線性)艰额,再根據(jù)已知數(shù)據(jù)去求解未知數(shù)據(jù)的值澄港。插值在數(shù)據(jù)領(lǐng)域非常常見,它的好處在于柄沮,可以盡量去還原數(shù)據(jù)本身的樣子回梧。
我們可以通過 interpolate() 方法完成線性插值。當(dāng)然祖搓,其他一些插值算法可以閱讀官方文檔了解狱意。

# 生成一個(gè) DataFrame
df = pd.DataFrame({'A': [1.1, 2.2, np.nan, 4.5, 5.7, 6.9],
                   'B': [.21, np.nan, np.nan, 3.1, 11.7, 13.2]})
df

對(duì)于上面存在的缺失值,如果通過前后值拯欧,或者平均值來填充是不太能反映出趨勢(shì)的详囤。這時(shí)候,插值最好使镐作。我們用默認(rèn)的線性插值試一試藏姐。

df_interpolate = df.interpolate()
df_interpolate

下圖展示了插值后的數(shù)據(jù),明顯看出插值結(jié)果符合數(shù)據(jù)的變化趨勢(shì)滑肉。如果按照前后數(shù)據(jù)順序填充包各,則無法做到這一點(diǎn)摘仅。

image.png

對(duì)于 interpolate() 支持的插值算法靶庙,也就是 method=。下面給出幾條選擇的建議:
如果你的數(shù)據(jù)增長速率越來越快娃属,可以選擇 method='quadratic'二次插值六荒。
如果數(shù)據(jù)集呈現(xiàn)出累計(jì)分布的樣子,推薦選擇 method='pchip'矾端。
如果需要填補(bǔ)缺省值掏击,以平滑繪圖為目標(biāo),推薦選擇 method='akima'秩铆。

數(shù)據(jù)可視化

當(dāng)我們的數(shù)據(jù)是以 DataFrame 格式呈現(xiàn)時(shí)砚亭,可以直接使用 Pandas 提供的 DataFrame.plot 方法調(diào)用 Matplotlib 接口繪制常見的圖形。
例如殴玛,我們使用上面插值后的數(shù)據(jù) df_interpolate 繪制線形圖捅膘。

df_interpolate.plot()

其他樣式的圖形也很簡單,指定 kind= 參數(shù)即可滚粟。

df_interpolate.plot(kind='bar')

其他用法

* 數(shù)據(jù)計(jì)算*寻仗,例如:DataFrame.add 等。
* 數(shù)據(jù)聚合*凡壤,例如:DataFrame.groupby 等署尤。
* 統(tǒng)計(jì)分析*耙替,例如:DataFrame.abs 等。
* 時(shí)間序列*曹体,例如:DataFrame.shift 等俗扇。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市混坞,隨后出現(xiàn)的幾起案子狐援,更是在濱河造成了極大的恐慌,老刑警劉巖究孕,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件啥酱,死亡現(xiàn)場離奇詭異,居然都是意外死亡厨诸,警方通過查閱死者的電腦和手機(jī)镶殷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來微酬,“玉大人绘趋,你說我怎么就攤上這事】殴埽” “怎么了陷遮?”我有些...
    開封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長垦江。 經(jīng)常有香客問我帽馋,道長,這世上最難降的妖魔是什么比吭? 我笑而不...
    開封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任绽族,我火速辦了婚禮,結(jié)果婚禮上衩藤,老公的妹妹穿的比我還像新娘吧慢。我一直安慰自己,他們只是感情好赏表,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開白布检诗。 她就那樣靜靜地躺著,像睡著了一般瓢剿。 火紅的嫁衣襯著肌膚如雪逢慌。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天跋选,我揣著相機(jī)與錄音涕癣,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛坠韩,可吹牛的內(nèi)容都是我干的距潘。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼只搁,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼音比!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起氢惋,我...
    開封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤洞翩,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后焰望,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體骚亿,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年熊赖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了来屠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡震鹉,死狀恐怖俱笛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情传趾,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布宽涌,位于F島的核電站蝶棋,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏玩裙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一段直、第九天 我趴在偏房一處隱蔽的房頂上張望吃溅。 院中可真熱鬧,春花似錦鸯檬、人聲如沸决侈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赖歌。三九已至枉圃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間庐冯,已是汗流浹背孽亲。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來泰國打工漏健, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留溺职,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓窟蓝,卻偏偏與公主長得像栖茉,于是被迫代替她去往敵國和親篮绿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容