日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Pandas中文官檔 ~ 基礎(chǔ)用法1

 liqualife 2019-10-25

呆鳥云:“在學(xué)習(xí) Python 數(shù)據(jù)分析的過程中,呆鳥發(fā)現(xiàn)直接看官檔就是牛逼啊,內(nèi)容全面、豐富、詳細(xì),而 Python 數(shù)據(jù)分析里最核心的莫過于 pandas,于是就想翻譯 pandas 官檔,于是就發(fā)現(xiàn)了 pypandas.cn 這個項目,于是就加入了 pandas 中文官檔翻譯小組,于是就沒時間更新公眾號,于是就犯懶想把翻譯與校譯的 pandas 當(dāng)公眾號文章發(fā)上來,于是今后大家就可以在這里看了。”


本節(jié)介紹 pandas 數(shù)據(jù)結(jié)構(gòu)的基礎(chǔ)用法。下列代碼創(chuàng)建示例數(shù)據(jù)對象:

In [1]: index = pd.date_range('1/1/2000', periods=8)

In [2]: s = pd.Series(np.random.randn(5), index=['a', 'b', 'c', 'd', 'e'])

In [3]: df = pd.DataFrame(np.random.randn(8, 3), index=index,
...: columns=['A', 'B', 'C'])
...:

Head 與 Tail

head() 與 tail() 用于快速預(yù)覽 Series 與 DataFrame,默認(rèn)顯示 5 條數(shù)據(jù),也可以指定要顯示的數(shù)量。

In [4]: long_series = pd.Series(np.random.randn(1000))

In [5]: long_series.head()
Out[5]:
0 -1.157892
1 -1.344312
2 0.844885
3 1.075770
4 -0.109050
dtype: float64

In [6]: long_series.tail(3)
Out[6]:
997 -0.289388
998 -1.020544
999 0.589993
dtype: float64

屬性與底層數(shù)據(jù)

Pandas 可以通過多個屬性訪問元數(shù)據(jù):

  • shape:
    • 輸出對象的軸維度,與 ndarray 一致
  • 軸標(biāo)簽
    • Series: Index (僅有此軸)
    • DataFrame: Index (行) 與

注意: 為屬性賦值是安全的!

In [7]: df[:2]
Out[7]:
A B C
2000-01-01 -0.173215 0.119209 -1.044236
2000-01-02 -0.861849 -2.104569 -0.494929

In [8]: df.columns = [x.lower() for x in df.columns]

In [9]: df
Out[9]:
a b c
2000-01-01 -0.173215 0.119209 -1.044236
2000-01-02 -0.861849 -2.104569 -0.494929
2000-01-03 1.071804 0.721555 -0.706771
2000-01-04 -1.039575 0.271860 -0.424972
2000-01-05 0.567020 0.276232 -1.087401
2000-01-06 -0.673690 0.113648 -1.478427
2000-01-07 0.524988 0.404705 0.577046
2000-01-08 -1.715002 -1.039268 -0.370647

Pandas 對象(Index, Series, DataFrame)相當(dāng)于數(shù)組的容器,用于存儲數(shù)據(jù),并執(zhí)行計算。大部分類型的底層數(shù)組都是 numpy.ndarray。不過,pandas 與第三方支持庫一般都會擴展 Numpy 類型系統(tǒng),添加自定義數(shù)組(見數(shù)據(jù)類型)。

獲取 Index 或 Series 里的數(shù)據(jù),請用 .array 屬性。

In [10]: s.array
Out[10]:
<PandasArray>
[ 0.4691122999071863, -0.2828633443286633, -1.5090585031735124,
-1.1356323710171934, 1.2121120250208506]
Length: 5, dtype: float64

In [11]: s.index.array
Out[11]:
<PandasArray>
['a', 'b', 'c', 'd', 'e']
Length: 5, dtype: object

array 一般指 ExtensionArray。至于什么是 ExtensionArray 及 pandas 為什么要用 ExtensionArray 不是本節(jié)要說明的內(nèi)容。更多信息請參閱數(shù)據(jù)類型。

提取 Numpy 數(shù)組,用 to_numpy() 或 numpy.asarray()。

In [12]: s.to_numpy()
Out[12]: array([ 0.4691, -0.2829, -1.5091, -1.1356, 1.2121])

In [13]: np.asarray(s)
Out[13]: array([ 0.4691, -0.2829, -1.5091, -1.1356, 1.2121])

Series 與 Index 的類型是 ExtensionArray 時, to_numpy() 會復(fù)制數(shù)據(jù),并強制轉(zhuǎn)換值。詳情見數(shù)據(jù)類型。

to_numpy() 可以控制 numpy.ndarray 生成的數(shù)據(jù)類型。以帶時區(qū)的 datetime 為例,Numpy 未提供時區(qū)信息的 datetime 數(shù)據(jù)類型,pandas 則提供了兩種表現(xiàn)形式:

  1. 一種是帶 Timestamp 的 numpy.ndarray,提供了正確的 tz 信息。

  2. 另一種是 datetime64[ns],這也是 numpy.ndarray,值被轉(zhuǎn)換為 UTC,但去掉了時區(qū)信息。

時區(qū)信息可以用 dtype=object 保存。

In [14]: ser = pd.Series(pd.date_range('2000', periods=2, tz='CET'))

In [15]: ser.to_numpy(dtype=object)
Out[15]:
array([Timestamp('2000-01-01 00:00:00+0100', tz='CET', freq='D'),
Timestamp('2000-01-02 00:00:00+0100', tz='CET', freq='D')],
dtype=object)

或用 dtype='datetime64[ns]' 去除。

In [16]: ser.to_numpy(dtype='datetime64[ns]')
Out[16]:
array(['1999-12-31T23:00:00.000000000', '2000-01-01T23:00:00.000000000'],
dtype='datetime64[ns]')

獲取 DataFrame 里的原數(shù)據(jù)略顯復(fù)雜。DataFrame 里所有列的數(shù)據(jù)類型都一樣時,DataFrame.to_numpy() 返回底層數(shù)據(jù):

In [17]: df.to_numpy()
Out[17]:
array([[-0.1732, 0.1192, -1.0442],
[-0.8618, -2.1046, -0.4949],
[ 1.0718, 0.7216, -0.7068],
[-1.0396, 0.2719, -0.425 ],
[ 0.567 , 0.2762, -1.0874],
[-0.6737, 0.1136, -1.4784],
[ 0.525 , 0.4047, 0.577 ],
[-1.715 , -1.0393, -0.3706]])

DataFrame 為同質(zhì)型數(shù)據(jù)時,pandas 直接修改原始 ndarray,所做修改會直接反應(yīng)在數(shù)據(jù)結(jié)構(gòu)里。對于異質(zhì)型數(shù)據(jù),即 DataFrame 列的數(shù)據(jù)類型不一樣時,就不是這種操作模式了。與軸標(biāo)簽不同,不能為值的屬性賦值。

::: tip 注意

處理異質(zhì)型數(shù)據(jù)時,輸出結(jié)果 ndarray 的數(shù)據(jù)類型適用于涉及的各類數(shù)據(jù)。若 DataFrame 里包含字符串,輸出結(jié)果的數(shù)據(jù)類型就是 object。要是只有浮點數(shù)或整數(shù),則輸出結(jié)果的數(shù)據(jù)類型是浮點數(shù)。

:::

以前,pandas 推薦用 Series.values 或 DataFrame.values 從 Series 或 DataFrame 里提取數(shù)據(jù)。舊有代碼庫或在線教程里仍在用這種操作,但其實 pandas 已經(jīng)對此做出了改進,現(xiàn)在推薦用 .array 或 to_numpy 這兩種方式提取數(shù)據(jù),別再用 .values 了。.values 有以下幾個缺點:

  1. Series 含擴展類型時,Series.values 無法判斷到底是該返回 Numpy array,還是返回 ExtensionArray。而 Series.array 則只返回 ExtensionArray,且不會復(fù)制數(shù)據(jù)。Series.to_numpy() 則返回 Numpy 數(shù)組,其代價是需要復(fù)制、并強制轉(zhuǎn)換數(shù)據(jù)的值。

  2. DataFrame 含多種數(shù)據(jù)類型時,DataFrame.values 會復(fù)制數(shù)據(jù),并將數(shù)據(jù)的值強制轉(zhuǎn)換同一種數(shù)據(jù)類型,這是一種代價較高的操作。DataFrame.to_numpy() 則返回 Numpy 數(shù)組,這種方式更清晰,也不會把 DataFrame 里的數(shù)據(jù)都當(dāng)作一種類型。

加速操作

借助 numexpr 與 bottleneck 支持庫,pandas 可以加速特定類型的二進制數(shù)值與布爾操作。

處理大型數(shù)據(jù)集時,這兩個支持庫特別有用,加速效果也非常明顯。 numexpr 使用智能分塊、緩存與多核技術(shù)。bottleneck 是一組專屬 cython 例程,處理含 nans 值的數(shù)組時,特別快。

請看下面這個例子(DataFrame 包含 100 列 X 10 萬行數(shù)據(jù)):

操作0.11.0版 (ms)舊版 (ms)提升比率
df1 > df213.32125.350.1063
df1 * df221.7136.630.5928
df1 + df222.0436.500.6039

強烈建議安裝這兩個支持庫,了解更多信息,請參閱推薦支持庫。

這兩個支持庫默認(rèn)為啟用狀態(tài),可用以下選項設(shè)置:

0.20.0 版新增

pd.set_option('compute.use_bottleneck', False)
pd.set_option('compute.use_numexpr', False)

二進制操作

pandas 數(shù)據(jù)結(jié)構(gòu)之間執(zhí)行二進制操作,要注意下列兩個關(guān)鍵點:
  • 多維(DataFrame)與低維(Series)對象之間的廣播機制;
  • 計算中的缺失值處理。

這兩個問題可以同時處理,但下面先介紹怎么分開處理。

匹配/廣播機制

DataFrame 支持 add()、sub()、mul()div() 及 radd()、rsub() 等方法執(zhí)行二進制操作。廣播機制重點關(guān)注輸入的 Series。通過 axis 關(guān)鍵字,匹配 index 或 columns 即可調(diào)用這些函數(shù)。

In [18]: df = pd.DataFrame({
....: 'one': pd.Series(np.random.randn(3), index=['a', 'b', 'c']),
....: 'two': pd.Series(np.random.randn(4), index=['a', 'b', 'c', 'd']),
....: 'three': pd.Series(np.random.randn(3), index=['b', 'c', 'd'])})
....:

In [19]: df
Out[19]:
one two three
a 1.394981 1.772517 NaN
b 0.343054 1.912123 -0.050390
c 0.695246 1.478369 1.227435
d NaN 0.279344 -0.613172

In [20]: row = df.iloc[1]

In [21]: column = df['two']

In [22]: df.sub(row, axis='columns')
Out[22]:
one two three
a 1.051928 -0.139606 NaN
b 0.000000 0.000000 0.000000
c 0.352192 -0.433754 1.277825
d NaN -1.632779 -0.562782

In [23]: df.sub(row, axis=1)
Out[23]:
one two three
a 1.051928 -0.139606 NaN
b 0.000000 0.000000 0.000000
c 0.352192 -0.433754 1.277825
d NaN -1.632779 -0.562782

In [24]: df.sub(column, axis='index')
Out[24]:
one two three
a -0.377535 0.0 NaN
b -1.569069 0.0 -1.962513
c -0.783123 0.0 -0.250933
d NaN 0.0 -0.892516

In [25]: df.sub(column, axis=0)
Out[25]:
one two three
a -0.377535 0.0 NaN
b -1.569069 0.0 -1.962513
c -0.783123 0.0 -0.250933
d NaN 0.0 -0.892516

還可以用 Series 對齊多重索引 DataFrame 的某一層級。

In [26]: dfmi = df.copy()

In [27]: dfmi.index = pd.MultiIndex.from_tuples([(1, 'a'), (1, 'b'),
....: (1, 'c'), (2, 'a')],
....: names=['first', 'second'])
....:

In [28]: dfmi.sub(column, axis=0, level='second')
Out[28]:
one two three
first second
1 a -0.377535 0.000000 NaN
b -1.569069 0.000000 -1.962513
c -0.783123 0.000000 -0.250933
2 a NaN -1.493173 -2.385688

Series 與 Index 還支持 divmod() 內(nèi)置函數(shù),該函數(shù)同時執(zhí)行向下取整除與模運算,返回兩個與左側(cè)類型相同的元組。示例如下:

In [29]: s = pd.Series(np.arange(10))

In [30]: s
Out[30]:
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
dtype: int64

In [31]: div, rem = divmod(s, 3)

In [32]: div
Out[32]:
0 0
1 0
2 0
3 1
4 1
5 1
6 2
7 2
8 2
9 3
dtype: int64

In [33]: rem
Out[33]:
0 0
1 1
2 2
3 0
4 1
5 2
6 0
7 1
8 2
9 0
dtype: int64

In [34]: idx = pd.Index(np.arange(10))

In [35]: idx
Out[35]: Int64Index([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype='int64')

In [36]: div, rem = divmod(idx, 3)

In [37]: div
Out[37]: Int64Index([0, 0, 0, 1, 1, 1, 2, 2, 2, 3], dtype='int64')

In [38]: rem
Out[38]: Int64Index([0, 1, 2, 0, 1, 2, 0, 1, 2, 0], dtype='int64')

divmod() 還支持元素級運算:

In [39]: div, rem = divmod(s, [2, 2, 3, 3, 4, 4, 5, 5, 6, 6])

In [40]: div
Out[40]:
0 0
1 0
2 0
3 1
4 1
5 1
6 1
7 1
8 1
9 1
dtype: int64

In [41]: rem
Out[41]:
0 0
1 1
2 2
3 0
4 0
5 1
6 1
7 2
8 2
9 3
dtype: int64

缺失值與填充缺失值操作

Series 與 DataFrame 的算數(shù)函數(shù)支持 fill_value 選項,即用指定值替換某個位置的缺失值。比如,兩個 DataFrame 相加,除非兩個 DataFrame 里同一個位置都有缺失值,其相加的和仍為 NaN,如果只有一個 DataFrame 里存在缺失值,則可以用 fill_value 指定一個值來替代 NaN,當(dāng)然,也可以用 fillna 把 NaN 替換為想要的值。

In [42]: df
Out[42]:
one two three
a 1.394981 1.772517 NaN
b 0.343054 1.912123 -0.050390
c 0.695246 1.478369 1.227435
d NaN 0.279344 -0.613172

In [43]: df2
Out[43]:
one two three
a 1.394981 1.772517 1.000000
b 0.343054 1.912123 -0.050390
c 0.695246 1.478369 1.227435
d NaN 0.279344 -0.613172

In [44]: df + df2
Out[44]:
one two three
a 2.789963 3.545034 NaN
b 0.686107 3.824246 -0.100780
c 1.390491 2.956737 2.454870
d NaN 0.558688 -1.226343

In [45]: df.add(df2, fill_value=0)
Out[45]:
one two three
a 2.789963 3.545034 1.000000
b 0.686107 3.824246 -0.100780
c 1.390491 2.956737 2.454870
d NaN 0.558688 -1.226343

比較操作

與上一小節(jié)的算數(shù)運算類似,Series 與 DataFrame 還支持 eqne、lt、gtle、ge 等二進制比較操作的方法:

序號縮寫英文中文
1eqequal to等于
2nenot equal to不等于
3ltless than小于
4gtgreater than大于
5leless than or equal to小于等于
6gegreater than or equal to大于等于
In [46]: df.gt(df2)
Out[46]:
one two three
a False False False
b False False False
c False False False
d False False False

In [47]: df2.ne(df)
Out[47]:
one two three
a False False True
b False False False
c False False False
d True False False

這些操作生成一個與左側(cè)輸入對象類型相同的 pandas 對象,即,dtype 為 bool。這些 boolean 對象可用于索引操作,參閱布爾索引小節(jié)。

布爾簡化

empty、any()all()、bool() 可以把數(shù)據(jù)匯總簡化至單個布爾值。

In [48]: (df > 0).all()
Out[48]:
one False
two True
three False
dtype: bool

In [49]: (df > 0).any()
Out[49]:
one True
two True
three True
dtype: bool

還可以進一步把上面的結(jié)果簡化為單個布爾值。

In [50]: (df > 0).any().any()
Out[50]: True

通過 empty 屬性,可以驗證 pandas 對象是否為空。

In [51]: df.empty
Out[51]: False

In [52]: pd.DataFrame(columns=list('ABC')).empty
Out[52]: True

用 bool() 方法驗證單元素 pandas 對象的布爾值。

In [53]: pd.Series([True]).bool()
Out[53]: True

In [54]: pd.Series([False]).bool()
Out[54]: False

In [55]: pd.DataFrame([[True]]).bool()
Out[55]: True

In [56]: pd.DataFrame([[False]]).bool()
Out[56]: False

::: danger 警告

以下代碼:

>>> if df:
... pass

>>> df and df2

上述代碼試圖比對多個值,因此,這兩種操作都會觸發(fā)錯誤:

ValueError: The truth value of an array is ambiguous. Use a.empty, a.any() or a.all().

:::

了解詳情,請參閱各種坑小節(jié)的內(nèi)容。

比較對象是否等效

一般情況下,多種方式都能得出相同的結(jié)果。以 df + df 與 df * 2 為例。應(yīng)用上一小節(jié)學(xué)到的知識,測試這兩種計算方式的結(jié)果是否一致,一般人都會用 (df + df == df * 2).all(),不過,這個表達(dá)式的結(jié)果是 False

In [57]: df + df == df * 2
Out[57]:
one two three
a True True False
b True True True
c True True True
d False True True

In [58]: (df + df == df * 2).all()
Out[58]:
one False
two True
three False
dtype: bool

注意:布爾型 DataFrame df + df == df * 2 中有 False 值!這是因為兩個 NaN 值的比較結(jié)果為不等:

In [59]: np.nan == np.nan
Out[59]: False

為了驗證數(shù)據(jù)是否等效,Series 與 DataFrame 等 N 維框架提供了 equals() 方法,,用這個方法驗證 NaN 值的結(jié)果為相等。

In [60]: (df + df).equals(df * 2)
Out[60]: True

注意:Series 與 DataFrame 索引的順序必須一致,驗證結(jié)果才能為 True

In [61]: df1 = pd.DataFrame({'col': ['foo', 0, np.nan]})

In [62]: df2 = pd.DataFrame({'col': [np.nan, 0, 'foo']}, index=[2, 1, 0])

In [63]: df1.equals(df2)
Out[63]: False

In [64]: df1.equals(df2.sort_index())
Out[64]: True

比較 array 型對象

用標(biāo)量值與 pandas 數(shù)據(jù)結(jié)構(gòu)對比數(shù)據(jù)元素非常簡單:

In [65]: pd.Series(['foo', 'bar', 'baz']) == 'foo'
Out[65]:
0 True
1 False
2 False
dtype: bool

In [66]: pd.Index(['foo', 'bar', 'baz']) == 'foo'
Out[66]: array([ True, False, False])

pandas 還能對比兩個等長 array 對象里的數(shù)據(jù)元素:

In [67]: pd.Series(['foo', 'bar', 'baz']) == pd.Index(['foo', 'bar', 'qux'])
Out[67]:
0 True
1 True
2 False
dtype: bool

In [68]: pd.Series(['foo', 'bar', 'baz']) == np.array(['foo', 'bar', 'qux'])
Out[68]:
0 True
1 True
2 False
dtype: bool

對比不等長的 Index 或 Series 對象會觸發(fā) ValueError

In [55]: pd.Series(['foo', 'bar', 'baz']) == pd.Series(['foo', 'bar'])
ValueError: Series lengths must match to compare

In [56]: pd.Series(['foo', 'bar', 'baz']) == pd.Series(['foo'])
ValueError: Series lengths must match to compare

注意:這里的操作與 Numpy 的廣播機制不同:

In [69]: np.array([1, 2, 3]) == np.array([2])
Out[69]: array([False, True, False])

Numpy 無法執(zhí)行廣播操作時,返回 False:

In [70]: np.array([1, 2, 3]) == np.array([1, 2])
Out[70]: False

合并重疊數(shù)據(jù)集

有時會合并兩個近似數(shù)據(jù)集,兩個數(shù)據(jù)集中,其中一個的數(shù)據(jù)比另一個多。比如,展示特定經(jīng)濟指標(biāo)的兩個數(shù)據(jù)序列,其中一個是“高質(zhì)量”指標(biāo),另一個是“低質(zhì)量”指標(biāo)。一般來說,低質(zhì)量序列可能包含更多的歷史數(shù)據(jù),或覆蓋更廣的數(shù)據(jù)。因此,要合并這兩個 DataFrame 對象,其中一個 DataFrame 中的缺失值將按指定條件用另一個 DataFrame 里類似標(biāo)簽中的數(shù)據(jù)進行填充。要實現(xiàn)這一操作,請用下列代碼中的 combine_first() 函數(shù)。

In [71]: df1 = pd.DataFrame({'A': [1., np.nan, 3., 5., np.nan],
....: 'B': [np.nan, 2., 3., np.nan, 6.]})
....:

In [72]: df2 = pd.DataFrame({'A': [5., 2., 4., np.nan, 3., 7.],
....: 'B': [np.nan, np.nan, 3., 4., 6., 8.]})
....:

In [73]: df1
Out[73]:
A B
0 1.0 NaN
1 NaN 2.0
2 3.0 3.0
3 5.0 NaN
4 NaN 6.0

In [74]: df2
Out[74]:
A B
0 5.0 NaN
1 2.0 NaN
2 4.0 3.0
3 NaN 4.0
4 3.0 6.0
5 7.0 8.0

In [75]: df1.combine_first(df2)
Out[75]:
A B
0 1.0 NaN
1 2.0 2.0
2 3.0 3.0
3 5.0 4.0
4 3.0 6.0
5 7.0 8.0

通用的 DataFrame 合并方法

上述 combine_first() 方法調(diào)用了更普適的 DataFrame.combine() 方法。該方法提取另一個 DataFrame 及合并器函數(shù),并將之與輸入的 DataFrame 對齊,再傳遞與 Series 配對的合并器函數(shù)(比如,名稱相同的列)。

下面的代碼復(fù)現(xiàn)了上述的 combine_first() 函數(shù):

In [76]: def combiner(x, y):
....: return np.where(pd.isna(x), y, x)
....:

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多