主頁 >  其他 > 【寶藏級】全網最全的Pandas詳細教程(2萬字總結)

【寶藏級】全網最全的Pandas詳細教程(2萬字總結)

2021-10-16 08:10:19 其他

【回爐重造】Python之Pandas詳細教程

  • 前言
    • 為什么要學習Pandas?
    • 什么是Pandas?
  • 1. Pandas的索引操作
    • 1. Series和DataFrame中的索引都是Index物件
    • 2. 索引物件不可變,保證了資料的安全
    • 3. 常見的Index種類
      • 3.1 Series索引
        • 1. index 指定行索引名
        • 2. 行索引
        • 3. 切片索引
        • 4. 不連續索引
        • 5. 布爾索引
      • 3.2 DataFrame索引
        • 1. columns 指定列索引名
        • 2. 列索引
        • 3. 不連續索引
    • 4. 高級索引:標簽、位置和混合
      • 1. loc 標簽索引
      • 2. iloc 位置索引
      • 3. ix 標簽與位置混合索引
  • 2. Pandas的對齊運算
    • 2.1 Series的對齊運算
      • 1. Series 按行、索引對齊
      • 2. Series的對齊運算
    • 2.2 DataFrame的對齊運算
      • 1. DataFrame按行、列索引對齊
      • 2. DataFrame的對齊運算
    • 2.3 填充未對齊的資料進行運算
      • fill\_value
  • 3. Pandas的函式應用
    • 3.1 apply 和 applymap
      • 1. 可直接使用NumPy的函式
      • 2. 通過apply將函式應用到列或行上
      • 3. 通過applymap將函式應用到每個資料上
    • 3.2 排序
      • 1. 索引排序
      • 2. 按值排序
    • 3.3 處理缺失資料
      • 1. 判斷是否存在缺失值:isnull\(\)
      • 2. 丟棄缺失資料:dropna\(\)
      • 3. 填充缺失資料:fillna\(\)
  • 4. 層級索引(hierarchical indexing)
    • 4.1 MultiIndex索引物件
    • 4.2 選取子集
      • 1. 外層選取:
      • 2. 內層選取:
    • 4.2 交換分層順序
      • swaplevel\(\)
    • 4.3 交換并排序分層
      • sortlevel\(\)
  • 5. Pandas統計計算和描述
    • 5.1 常用的統計計算
      • sum, mean, max, min…
    • 5.2 常用的統計描述
      • describe 產生多個統計資料
    • 5.3 常用的統計描述方法
  • 6. 資料讀取與存盤
    • 6.1 csv檔案
    • 6.2 資料庫互動
  • 7. 資料清洗
    • 7.1 資料清洗和準備
      • 1. 處理缺失資料
      • 2. 資料轉換
        • 2.1 處理重復資料
        • 2.2 duplicated\(\)是否為重復行
        • 2.4 drop\_duplicates\(\)過濾重復行
        • 2.5 利用函式或映射進行資料轉換
        • 2.6 替換值
          • replace根據值的內容進行替換
      • 3. 字串操作
        • 3.1 字串方法
        • 3.2 正則運算式方法
        • 3.3 pandas字串函式
    • 7.2 資料合并
      • 1. 資料合并\(pd.merge\)
        • 1. 處理重復列名
        • 2. 按索引連接
      • 2. 資料合并\(pd.concat\)
        • 1. NumPy的concat
        • 2. pd.concat
    • 7.3 重塑
      • 1. stack
      • 2. unstack
  • 8. 資料分組聚合
    • 8.1 聚合
  • 9. Pandas中的時間序列
    • 9.1 時間和日期資料型別及其工具
    • 9.2 字串和datetime的相互轉換
      • 時間序列基礎
    • 9.3 索引、選取、子集構造
    • 9.4 日期的范圍、頻率以及移動
      • 生成日期范圍
      • 重采樣及頻率轉換

前言

在這里插入圖片描述

為什么要學習Pandas?

那么問題來了

numpy已經能夠幫助我們處理資料,能夠結合matplotlib解決我們資料分析的問題,那么pandas學習的目的在什么地方呢?

numpy能夠幫我們處理處理數值型資料,但是這還不夠, 很多時候,我們的資料除了數值之外,還有字串,還有時間序列等

比如:我們通過爬蟲獲取到了存盤在資料庫中的資料

所以,pandas出現了,

什么是Pandas?

Pandas的名稱來自于面板資料(panel data)

Pandas是一個強大的分析結構化資料的工具集,基于NumPy構建,提供了高級資料結構資料操作工具,它是使Python成為強大而高效的資料分析環境的重要因素之一,

  • 一個強大的分析和操作大型結構化資料集所需的工具集

  • 基礎是NumPy,提供了高性能矩陣的運算

  • 提供了大量能夠快速便捷地處理資料的函式和方法

  • 應用于資料挖掘,資料分析

  • 提供資料清洗功能

官網

http://pandas.pydata.org/

1. Pandas的索引操作

索引物件Index

1. Series和DataFrame中的索引都是Index物件

示例代碼:

print(type(ser_obj.index))
print(type(df_obj2.index))

print(df_obj2.index)

運行結果:

<class 'pandas.indexes.range.RangeIndex'>
<class 'pandas.indexes.numeric.Int64Index'>
Int64Index([0, 1, 2, 3], dtype='int64')

2. 索引物件不可變,保證了資料的安全

示例代碼:

# 索引物件不可變
df_obj2.index[0] = 2

運行結果:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-23-7f40a356d7d1> in <module>()
      1 # 索引物件不可變
----> 2 df_obj2.index[0] = 2

/Users/Power/anaconda/lib/python3.6/site-packages/pandas/indexes/base.py in __setitem__(self, key, value)
   1402 
   1403     def __setitem__(self, key, value):
-> 1404         raise TypeError("Index does not support mutable operations")
   1405 
   1406     def __getitem__(self, key):

TypeError: Index does not support mutable operations

3. 常見的Index種類

  • Index,索引
  • Int64Index,整數索引
  • MultiIndex,層級索引
  • DatetimeIndex,時間戳型別

3.1 Series索引

1. index 指定行索引名

示例代碼:

ser_obj = pd.Series(range(5), index = ['a', 'b', 'c', 'd', 'e'])
print(ser_obj.head())

運行結果:

a    0
b    1
c    2
d    3
e    4
dtype: int64

2. 行索引

ser_obj[‘label’], ser_obj[pos]

示例代碼:

# 行索引
print(ser_obj['b'])
print(ser_obj[2])

運行結果:

1
2

3. 切片索引

ser_obj[2:4], ser_obj[‘label1’: ’label3’]

注意,按索引名切片操作時,是包含終止索引的,

示例代碼:

# 切片索引
print(ser_obj[1:3])
print(ser_obj['b':'d'])

運行結果:

b    1
c    2
dtype: int64
b    1
c    2
d    3
dtype: int64

4. 不連續索引

ser_obj[[‘label1’, ’label2’, ‘label3’]]

示例代碼:

# 不連續索引
print(ser_obj[[0, 2, 4]])
print(ser_obj[['a', 'e']])

運行結果:

a    0
c    2
e    4
dtype: int64
a    0
e    4
dtype: int64

5. 布爾索引

示例代碼:

# 布爾索引
ser_bool = ser_obj > 2
print(ser_bool)
print(ser_obj[ser_bool])

print(ser_obj[ser_obj > 2])

運行結果:

a    False
b    False
c    False
d     True
e     True
dtype: bool
d    3
e    4
dtype: int64
d    3
e    4
dtype: int64

3.2 DataFrame索引

1. columns 指定列索引名

示例代碼:

import numpy as np

df_obj = pd.DataFrame(np.random.randn(5,4), columns = ['a', 'b', 'c', 'd'])
print(df_obj.head())

運行結果:

          a         b         c         d
0 -0.241678  0.621589  0.843546 -0.383105
1 -0.526918 -0.485325  1.124420 -0.653144
2 -1.074163  0.939324 -0.309822 -0.209149
3 -0.716816  1.844654 -2.123637 -1.323484
4  0.368212 -0.910324  0.064703  0.486016

在這里插入圖片描述

2. 列索引

df_obj[[‘label’]]

示例代碼:

# 列索引
print(df_obj['a']) # 回傳Series型別

運行結果:

0   -0.241678
1   -0.526918
2   -1.074163
3   -0.716816
4    0.368212
Name: a, dtype: float64

3. 不連續索引

df_obj[[‘label1’, ‘label2’]]

示例代碼:

# 不連續索引
print(df_obj[['a','c']])

運行結果:

          a         c
0 -0.241678  0.843546
1 -0.526918  1.124420
2 -1.074163 -0.309822
3 -0.716816 -2.123637
4  0.368212  0.064703

4. 高級索引:標簽、位置和混合

Pandas的高級索引有3種

1. loc 標簽索引

DataFrame 不能直接切片,可以通過loc來做切片

loc是基于標簽名的索引,也就是我們自定義的索引名

示例代碼:

# 標簽索引 loc
# Series
print(ser_obj['b':'d'])
print(ser_obj.loc['b':'d'])

# DataFrame
print(df_obj['a'])

# 第一個引數索引行,第二個引數是列
print(df_obj.loc[0:2, 'a'])

運行結果:

b    1
c    2
d    3
dtype: int64
b    1
c    2
d    3
dtype: int64

0   -0.241678
1   -0.526918
2   -1.074163
3   -0.716816
4    0.368212
Name: a, dtype: float64
0   -0.241678
1   -0.526918
2   -1.074163
Name: a, dtype: float64

2. iloc 位置索引

作用和loc一樣,不過是基于索引編號來索引

示例代碼:

# 整型位置索引 iloc
# Series
print(ser_obj[1:3])
print(ser_obj.iloc[1:3])

# DataFrame
print(df_obj.iloc[0:2, 0]) # 注意和df_obj.loc[0:2, 'a']的區別

運行結果:

b    1
c    2
dtype: int64
b    1
c    2
dtype: int64

0   -0.241678
1   -0.526918
Name: a, dtype: float64

3. ix 標簽與位置混合索引

ix是以上二者的綜合,既可以使用索引編號,又可以使用自定義索引,要視情況不同來使用,

如果索引既有數字又有英文,那么這種方式是不建議使用的,容易導致定位的混亂,

示例代碼:

# 混合索引 ix
# Series
print(ser_obj.ix[1:3])
print(ser_obj.ix['b':'c'])

# DataFrame
print(df_obj.loc[0:2, 'a'])
print(df_obj.ix[0:2, 0])

運行結果:

b    1
c    2
dtype: int64
b    1
c    2
dtype: int64

0   -0.241678
1   -0.526918
2   -1.074163
Name: a, dtype: float64

注意

DataFrame索引操作,可將其看作ndarray的索引操作

標簽的切片索引是包含末尾位置的

2. Pandas的對齊運算

Pandas的對齊運算是資料清洗的重要程序,可以按索引對齊進行運算,如果沒對齊的位置則補NaN,最后也可以填充NaN

2.1 Series的對齊運算

1. Series 按行、索引對齊

示例代碼:

s1 = pd.Series(range(10, 20), index = range(10))
s2 = pd.Series(range(20, 25), index = range(5))

print('s1: ' )
print(s1)

print('') 

print('s2: ')
print(s2)

運行結果:

s1: 
0    10
1    11
2    12
3    13
4    14
5    15
6    16
7    17
8    18
9    19
dtype: int64

s2: 
0    20
1    21
2    22
3    23
4    24
dtype: int64

2. Series的對齊運算

示例代碼:

# Series 對齊運算
s1 + s2

運行結果:

0    30.0
1    32.0
2    34.0
3    36.0
4    38.0
5     NaN
6     NaN
7     NaN
8     NaN
9     NaN
dtype: float64

2.2 DataFrame的對齊運算

1. DataFrame按行、列索引對齊

示例代碼:

df1 = pd.DataFrame(np.ones((2,2)), columns = ['a', 'b'])
df2 = pd.DataFrame(np.ones((3,3)), columns = ['a', 'b', 'c'])

print('df1: ')
print(df1)

print('') 
print('df2: ')
print(df2)

運行結果:

df1: 
     a    b
0  1.0  1.0
1  1.0  1.0

df2: 
     a    b    c
0  1.0  1.0  1.0
1  1.0  1.0  1.0
2  1.0  1.0  1.0

2. DataFrame的對齊運算

示例代碼:

# DataFrame對齊操作
df1 + df2

運行結果:

     a    b   c
0  2.0  2.0 NaN
1  2.0  2.0 NaN
2  NaN  NaN NaN

2.3 填充未對齊的資料進行運算

fill_value

使用add,sub,div,mul的同時,

通過fill_value指定填充值,未對齊的資料將和填充值做運算

示例代碼:

print(s1)
print(s2)
s1.add(s2, fill_value = -1)

print(df1)
print(df2)
df1.sub(df2, fill_value = 2.)

運行結果:

# print(s1)
0    10
1    11
2    12
3    13
4    14
5    15
6    16
7    17
8    18
9    19
dtype: int64

# print(s2)
0    20
1    21
2    22
3    23
4    24
dtype: int64

# s1.add(s2, fill_value = -1)
0    30.0
1    32.0
2    34.0
3    36.0
4    38.0
5    14.0
6    15.0
7    16.0
8    17.0
9    18.0
dtype: float64


# print(df1)
     a    b
0  1.0  1.0
1  1.0  1.0

# print(df2)
     a    b    c
0  1.0  1.0  1.0
1  1.0  1.0  1.0
2  1.0  1.0  1.0


# df1.sub(df2, fill_value = 2.)
     a    b    c
0  0.0  0.0  1.0
1  0.0  0.0  1.0
2  1.0  1.0  1.0

算術方法表:

方法描述
add,radd加法(+)
sub,rsub減法(-)
div,rdiv除法(/)
floordiv,rfllordiv整除(//)
mul,rmul乘法(*)
pow,rpow冪次方(**)

3. Pandas的函式應用

3.1 apply 和 applymap

1. 可直接使用NumPy的函式

示例代碼:

# Numpy ufunc 函式
df = pd.DataFrame(np.random.randn(5,4) - 1)
print(df)

print(np.abs(df))

運行結果:

          0         1         2         3
0 -0.062413  0.844813 -1.853721 -1.980717
1 -0.539628 -1.975173 -0.856597 -2.612406
2 -1.277081 -1.088457 -0.152189  0.530325
3 -1.356578 -1.996441  0.368822 -2.211478
4 -0.562777  0.518648 -2.007223  0.059411

          0         1         2         3
0  0.062413  0.844813  1.853721  1.980717
1  0.539628  1.975173  0.856597  2.612406
2  1.277081  1.088457  0.152189  0.530325
3  1.356578  1.996441  0.368822  2.211478
4  0.562777  0.518648  2.007223  0.059411

2. 通過apply將函式應用到列或行上

示例代碼:

# 使用apply應用行或列資料
#f = lambda x : x.max()
print(df.apply(lambda x : x.max()))

運行結果:

0   -0.062413
1    0.844813
2    0.368822
3    0.530325
dtype: float64

注意指定軸的方向,默認axis=0,方向是列

示例代碼:

# 指定軸方向,axis=1,方向是行
print(df.apply(lambda x : x.max(), axis=1))

運行結果:

0    0.844813
1   -0.539628
2    0.530325
3    0.368822
4    0.518648
dtype: float64

3. 通過applymap將函式應用到每個資料上

示例代碼:

# 使用applymap應用到每個資料
f2 = lambda x : '%.2f' % x
print(df.applymap(f2))

運行結果:

       0      1      2      3
0  -0.06   0.84  -1.85  -1.98
1  -0.54  -1.98  -0.86  -2.61
2  -1.28  -1.09  -0.15   0.53
3  -1.36  -2.00   0.37  -2.21
4  -0.56   0.52  -2.01   0.06

3.2 排序

1. 索引排序

sort_index()

排序默認使用升序排序,ascending=False 為降序排序

示例代碼:

# Series
s4 = pd.Series(range(10, 15), index = np.random.randint(5, size=5))
print(s4)

# 索引排序
s4.sort_index() # 0 0 1 3 3

運行結果:

0    10
3    11
1    12
3    13
0    14
dtype: int64

0    10
0    14
1    12
3    11
3    13
dtype: int64

對DataFrame操作時注意軸方向

示例代碼:

# DataFrame
df4 = pd.DataFrame(np.random.randn(3, 5), 
                   index=np.random.randint(3, size=3),
                   columns=np.random.randint(5, size=5))
print(df4)

df4_isort = df4.sort_index(axis=1, ascending=False)
print(df4_isort) # 4 2 1 1 0

運行結果:

          1         4         0         1         2
2 -0.416686 -0.161256  0.088802 -0.004294  1.164138
1 -0.671914  0.531256  0.303222 -0.509493 -0.342573
1  1.988321 -0.466987  2.787891 -1.105912  0.889082

          4         2         1         1         0
2 -0.161256  1.164138 -0.416686 -0.004294  0.088802
1  0.531256 -0.342573 -0.671914 -0.509493  0.303222
1 -0.466987  0.889082  1.988321 -1.105912  2.787891

2. 按值排序

sort_values(by=‘column name’)

根據某個唯一的列名進行排序,如果有其他相同列名則報錯,

示例代碼:

# 按值排序
df4_vsort = df4.sort_values(by=0, ascending=False)
print(df4_vsort)

運行結果:

          1         4         0         1         2
1  1.988321 -0.466987  2.787891 -1.105912  0.889082
1 -0.671914  0.531256  0.303222 -0.509493 -0.342573
2 -0.416686 -0.161256  0.088802 -0.004294  1.164138

3.3 處理缺失資料

示例代碼:

df_data = pd.DataFrame([np.random.randn(3), [1., 2., np.nan],
                       [np.nan, 4., np.nan], [1., 2., 3.]])
print(df_data.head())

運行結果:

          0         1         2
0 -0.281885 -0.786572  0.487126
1  1.000000  2.000000       NaN
2       NaN  4.000000       NaN
3  1.000000  2.000000  3.000000

1. 判斷是否存在缺失值:isnull()

示例代碼:

# isnull
print(df_data.isnull())

運行結果:

       0      1      2
0  False  False  False
1  False  False   True
2   True  False   True
3  False  False  False

2. 丟棄缺失資料:dropna()

根據axis軸方向,丟棄包含NaN的行或列, 示例代碼:

# dropna
print(df_data.dropna())  # 默認是按行

print(df_data.dropna(axis=1))  # axis=1是按列

運行結果:

          0         1         2
0 -0.281885 -0.786572  0.487126
3  1.000000  2.000000  3.000000

          1
0 -0.786572
1  2.000000
2  4.000000
3  2.000000

3. 填充缺失資料:fillna()

示例代碼:

# fillna
print(df_data.fillna(-100.))

運行結果:

            0         1           2
0   -0.281885 -0.786572    0.487126
1    1.000000  2.000000 -100.000000
2 -100.000000  4.000000 -100.000000
3    1.000000  2.000000    3.000000

4. 層級索引(hierarchical indexing)

下面創建一個Series, 在輸入索引Index時,輸入了由兩個子list組成的list,第一個子list是外層索引,第二個list是內層索引,

示例代碼:

import pandas as pd
import numpy as np

ser_obj = pd.Series(np.random.randn(12),index=[
                ['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'd'],
                [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]
            ])
print(ser_obj)

運行結果:

a  0    0.099174
   1   -0.310414
   2   -0.558047
b  0    1.742445
   1    1.152924
   2   -0.725332
c  0   -0.150638
   1    0.251660
   2    0.063387
d  0    1.080605
   1    0.567547
   2   -0.154148
dtype: float64

4.1 MultiIndex索引物件

  • 列印這個Series的索引型別,顯示是MultiIndex

  • 直接將索引列印出來,可以看到有lavels,和labels兩個資訊,levels表示兩個層級中分別有那些標簽,labels是每個位置分別是什么標簽,

示例代碼:

print(type(ser_obj.index))
print(ser_obj.index)

運行結果:

<class 'pandas.indexes.multi.MultiIndex'>
MultiIndex(levels=[['a', 'b', 'c', 'd'], [0, 1, 2]],
           labels=[[0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3], [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]])

4.2 選取子集

  • 根據索引獲取資料,因為現在有兩層索引,當通過外層索引獲取資料的時候,可以直接利用外層索引的標簽來獲取,

  • 當要通過內層索引獲取資料的時候,在list中傳入兩個元素,前者是表示要選取的外層索引,后者表示要選取的內層索引,

1. 外層選取:

ser_obj[‘outer_label’]

示例代碼:

# 外層選取
print(ser_obj['c'])

運行結果:

0   -1.362096
1    1.558091
2   -0.452313
dtype: float64

2. 內層選取:

ser_obj[:, ‘inner_label’]

示例代碼:

# 內層選取
print(ser_obj[:, 2])

運行結果:

a    0.826662
b    0.015426
c   -0.452313
d   -0.051063
dtype: float64

常用于分組操作、透視表的生成等


4.2 交換分層順序

swaplevel()

.swaplevel( )交換內層與外層索引,

示例代碼:

print(ser_obj.swaplevel())

運行結果:

0  a    0.099174
1  a   -0.310414
2  a   -0.558047
0  b    1.742445
1  b    1.152924
2  b   -0.725332
0  c   -0.150638
1  c    0.251660
2  c    0.063387
0  d    1.080605
1  d    0.567547
2  d   -0.154148
dtype: float64

4.3 交換并排序分層

sortlevel()

.sortlevel( )先對外層索引進行排序,再對內層索引進行排序,默認是升序,

示例代碼:

# 交換并排序分層
print(ser_obj.swaplevel().sortlevel())

運行結果:

0  a    0.099174
   b    1.742445
   c   -0.150638
   d    1.080605
1  a   -0.310414
   b    1.152924
   c    0.251660
   d    0.567547
2  a   -0.558047
   b   -0.725332
   c    0.063387
   d   -0.154148
dtype: float64

5. Pandas統計計算和描述

示例代碼:

arr1 = np.random.rand(4,3)
pd1 = pd.DataFrame(arr1,columns=list('ABC'),index=list('abcd'))
f = lambda x: '%.2f'% x
pd2 = pd1.applymap(f).astype(float)
pd2

運行結果:

      A            B           C
a    0.87        0.26        0.67
b    0.69        0.89        0.17
c    0.94        0.33        0.04
d    0.35        0.46        0.29

5.1 常用的統計計算

sum, mean, max, min…

axis=0 按列統計,axis=1按行統計

skipna 排除缺失值, 默認為True

示例代碼:

pd2.sum() #默認把這一列的Series計算,所有行求和
pd2.sum(axis='columns') #指定求每一行的所有列的和
pd2.idxmax()#查看每一列所有行的最大值所在的標簽索引,同樣我們也可以通過axis='columns'求每一行所有列的最大值的標簽索引

運行結果:

A    2.85
B    1.94
C    1.17
dtype: float64


a    1.80
b    1.75
c    1.31
d    1.10
dtype: float64


A    c
B    b
C    a
dtype: object

在這里插入圖片描述

5.2 常用的統計描述

describe 產生多個統計資料

示例代碼:

pd2.describe()#查看匯總

運行結果:

                A        B        C
count      4.000000    4.00000        4.000000
mean       0.712500    0.48500        0.292500
std        0.263613    0.28243        0.271585
min        0.350000    0.26000        0.040000
25%        0.605000    0.31250        0.137500
50%        0.780000    0.39500        0.230000
75%        0.887500    0.56750        0.385000
max        0.940000    0.89000        0.670000
#百分比:除以原來的量
pd2.pct_change() #查看行的百分比變化,同樣指定axis='columns'列與列的百分比變化
     A                 B                C
a    NaN              NaN             NaN
b    -0.206897        2.423077        -0.746269
c    0.362319        -0.629213        -0.764706
d    -0.627660        0.393939        6.250000

5.3 常用的統計描述方法

在這里插入圖片描述

6. 資料讀取與存盤

在這里插入圖片描述
在這里插入圖片描述

6.1 csv檔案

  1. 讀取csv檔案read_csv(file_path or buf,usecols,encoding):file_path:檔案路徑,usecols:指定讀取的列名,encoding:編碼

    data = pd.read_csv('d:/test_data/food_rank.csv',encoding='utf8')
    data.head()
        name    num
    0    酥油茶    219.0
    1    青稞酒    95.0
    2    酸奶    62.0
    3    糌粑    16.0
    4    琵琶肉    2.0
    
    #指定讀取的列名
    data = pd.read_csv('d:/test_data/food_rank.csv',usecols=['name'])
    data.head()
        name
    0    酥油茶
    1    青稞酒
    2    酸奶
    3    糌粑
    4    琵琶肉
    
    #如果檔案路徑有中文,則需要知道引數engine='python'
    data = pd.read_csv('d:/資料/food_rank.csv',engine='python',encoding='utf8')
    data.head()
        name    num
    0    酥油茶    219.0
    1    青稞酒    95.0
    2    酸奶    62.0
    3    糌粑    16.0
    4    琵琶肉    2.0
    #建議檔案路徑和檔案名,不要出現中文
    
  2. 寫入csv檔案

    DataFrame:to_csv(file_path or buf,sep,columns,header,index,na_rep,mode):file_path保存檔案路徑,默認None,sep:分隔符,默認’,’ ,columns:是否保留某列資料,默認None,header是否保留列名,默認True,index:是否保留行索引,默認True,na_rep:指定字串來代替空值,默認是空字符,mode:默認’w’,追加’a’

 **Series**:`Series.to_csv`\
 (_path=None_,_index=True_,_sep='_,_'_,_na\_rep=''_,_header=False_,_mode='w'_,_encoding=None_\)

6.2 資料庫互動

  • pandas
  • sqlalchemy
  • pymysql
# 匯入必要模塊
import pandas as pd
from sqlalchemy import create_engine

#初始化資料庫連接
#用戶名root 密碼   埠 3306  資料庫 db2
engine = create_engine('mysql+pymysql://root:@localhost:3306/db2')
#查詢陳述句
sql = '''
    select * from class;
'''
#兩個引數   sql陳述句  資料庫連接
df = pd.read_sql(sql,engine)
df

在這里插入圖片描述

#新建
df = pd.DataFrame({'id':[1,2,3,4],'num':[34,56,78,90]})
df = pd.read_csv('ex1.csv')
# #寫入到資料庫
df.to_sql('df2',engine,index=False)
print("ok")

進入資料庫查看

在這里插入圖片描述

7. 資料清洗

7.1 資料清洗和準備

資料清洗是資料分析關鍵的一步,直接影響之后的處理作業

資料需要修改嗎?有什么需要修改的嗎?資料應該怎么調整才能適用于接下來的分析和挖掘?

是一個迭代的程序,實際專案中可能需要不止一次地執行這些清洗操作

1. 處理缺失資料

  • pd.fillna()
  • pd.dropna()

在這里插入圖片描述

2. 資料轉換

2.1 處理重復資料

2.2 duplicated()是否為重復行

duplicated\(\): 回傳布爾型Series表示每行是否為重復行

示例代碼:

import numpy as np
import pandas as pd

df_obj = pd.DataFrame({'data1' : ['a'] * 4 + ['b'] * 4,
                       'data2' : np.random.randint(0, 4, 8)})
print(df_obj)

print(df_obj.duplicated())

運行結果:

# print(df_obj)
  data1  data2
0     a      3
1     a      2
2     a      3
3     a      3
4     b      1
5     b      0
6     b      3
7     b      0

# print(df_obj.duplicated())
0    False
1    False
2     True
3     True
4    False
5    False
6    False
7     True
dtype: bool

2.4 drop_duplicates()過濾重復行

  • 默認判斷全部列
  • 可指定按某些列判斷

示例代碼:

print(df_obj.drop_duplicates())
print(df_obj.drop_duplicates('data2'))

運行結果:

# print(df_obj.drop_duplicates())
  data1  data2
0     a      3
1     a      2
4     b      1
5     b      0
6     b      3

# print(df_obj.drop_duplicates('data2'))
  data1  data2
0     a      3
1     a      2
4     b      1
5     b      0

2.5 利用函式或映射進行資料轉換

根據map傳入的函式對每行或每列進行轉換

示例代碼:

ser_obj = pd.Series(np.random.randint(0,10,10))
print(ser_obj)

print(ser_obj.map(lambda x : x ** 2))

運行結果:

# print(ser_obj)
0    1
1    4
2    8
3    6
4    8
5    6
6    6
7    4
8    7
9    3
dtype: int64

# print(ser_obj.map(lambda x : x ** 2))
0     1
1    16
2    64
3    36
4    64
5    36
6    36
7    16
8    49
9     9
dtype: int64

2.6 替換值

replace根據值的內容進行替換

示例代碼:

# 單個值替換單個值
print(ser_obj.replace(1, -100))

# 多個值替換一個值
print(ser_obj.replace([6, 8], -100))

# 多個值替換多個值
print(ser_obj.replace([4, 7], [-100, -200]))

運行結果:

# print(ser_obj.replace(1, -100))
0   -100
1      4
2      8
3      6
4      8
5      6
6      6
7      4
8      7
9      3
dtype: int64

# print(ser_obj.replace([6, 8], -100))
0      1
1      4
2   -100
3   -100
4   -100
5   -100
6   -100
7      4
8      7
9      3
dtype: int64

# print(ser_obj.replace([4, 7], [-100, -200]))
0      1
1   -100
2      8
3      6
4      8
5      6
6      6
7   -100
8   -200
9      3
dtype: int64

3. 字串操作

3.1 字串方法

在這里插入圖片描述

在這里插入圖片描述

3.2 正則運算式方法

在這里插入圖片描述

3.3 pandas字串函式

在這里插入圖片描述

7.2 資料合并

1. 資料合并(pd.merge)

  • 根據單個或多個鍵將不同DataFrame的行連接起來

  • 類似資料庫的連接操作

  • pd.merge:(left, right, how=‘inner’,on=None,left_on=None, right_on=None )

    left:合并時左邊的DataFrame

    right:合并時右邊的DataFrame

    how:合并的方式,默認’inner’, ‘outer’, ‘left’, ‘right’

    on:需要合并的列名,必須兩邊都有的列名,并以 left 和 right 中的列名的交集作為連接鍵

    left_on: left Dataframe中用作連接鍵的列

    right_on: right Dataframe中用作連接鍵的列

  • 內連接 inner:對兩張表都有的鍵的交集進行聯合

在這里插入圖片描述

  • 全連接 outer:對兩者表的都有的鍵的并集進行聯合

在這里插入圖片描述

  • 左連接 left:對所有左表的鍵進行聯合

在這里插入圖片描述

  • 右連接 right:對所有右表的鍵進行聯合

在這里插入圖片描述

示例代碼:

import pandas as pd
import numpy as np

left = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
                      'A': ['A0', 'A1', 'A2', 'A3'],
                       'B': ['B0', 'B1', 'B2', 'B3']})

right = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
                      'C': ['C0', 'C1', 'C2', 'C3'],
                      'D': ['D0', 'D1', 'D2', 'D3']})

pd.merge(left,right,on='key') #指定連接鍵key

運行結果:

key    A    B    C    D
0    K0    A0    B0    C0    D0
1    K1    A1    B1    C1    D1
2    K2    A2    B2    C2    D2
3    K3    A3    B3    C3    D3

在這里插入圖片描述

示例代碼:

left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
                    'key2': ['K0', 'K1', 'K0', 'K1'],
                    'A': ['A0', 'A1', 'A2', 'A3'],
                    'B': ['B0', 'B1', 'B2', 'B3']})

right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],
                      'key2': ['K0', 'K0', 'K0', 'K0'],
                      'C': ['C0', 'C1', 'C2', 'C3'],
                      'D': ['D0', 'D1', 'D2', 'D3']})

pd.merge(left,right,on=['key1','key2']) #指定多個鍵,進行合并

運行結果:

    key1    key2    A    B    C    D
0    K0    K0    A0    B0    C0    D0
1    K1    K0    A2    B2    C1    D1
2    K1    K0    A2    B2    C2    D2

在這里插入圖片描述

#指定左連接

left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
                    'key2': ['K0', 'K1', 'K0', 'K1'],
                    'A': ['A0', 'A1', 'A2', 'A3'],
                    'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],
                      'key2': ['K0', 'K0', 'K0', 'K0'],
                      'C': ['C0', 'C1', 'C2', 'C3'],
                      'D': ['D0', 'D1', 'D2', 'D3']})

pd.merge(left, right, how='left', on=['key1', 'key2'])
    key1    key2          A    B    C    D
0    K0        K0        A0    B0    C0    D0
1    K0        K1        A1    B1    NaN    NaN
2    K1        K0        A2    B2    C1    D1
3    K1        K0        A2    B2    C2    D2
4    K2        K1        A3    B3    NaN    NaN

在這里插入圖片描述

#指定右連接

left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
                    'key2': ['K0', 'K1', 'K0', 'K1'],
                    'A': ['A0', 'A1', 'A2', 'A3'],
                    'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],
                      'key2': ['K0', 'K0', 'K0', 'K0'],
                      'C': ['C0', 'C1', 'C2', 'C3'],
                      'D': ['D0', 'D1', 'D2', 'D3']})
pd.merge(left, right, how='right', on=['key1', 'key2'])
    key1    key2          A    B    C    D
0    K0        K0        A0    B0    C0    D0
1    K1        K0        A2    B2    C1    D1
2    K1        K0        A2    B2    C2    D2
3    K2        K0        NaN    NaN    C3    D3

在這里插入圖片描述

默認是“內連接”(inner),即結果中的鍵是交集

how: 指定連接方式

“外連接”(outer),結果中的鍵是并集

示例代碼:

left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
                    'key2': ['K0', 'K1', 'K0', 'K1'],
                    'A': ['A0', 'A1', 'A2', 'A3'],
                    'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],
                      'key2': ['K0', 'K0', 'K0', 'K0'],
                      'C': ['C0', 'C1', 'C2', 'C3'],
                      'D': ['D0', 'D1', 'D2', 'D3']})
                      
pd.merge(left,right,how='outer',on=['key1','key2'])

運行結果:

key1    key2    A    B    C    D
0    K0    K0    A0    B0    C0    D0
1    K0    K1    A1    B1    NaN    NaN
2    K1    K0    A2    B2    C1    D1
3    K1    K0    A2    B2    C2    D2
4    K2    K1    A3    B3    NaN    NaN
5    K2    K0    NaN    NaN    C3    D3

在這里插入圖片描述

1. 處理重復列名

引數suffixes:默認為_x, _y

示例代碼:

# 處理重復列名
df_obj1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
                        'data' : np.random.randint(0,10,7)})
df_obj2 = pd.DataFrame({'key': ['a', 'b', 'd'],
                        'data' : np.random.randint(0,10,3)})

print(pd.merge(df_obj1, df_obj2, on='key', suffixes=('_left', '_right')))

運行結果:

   data_left key  data_right
0          9   b           1
1          5   b           1
2          1   b           1
3          2   a           8
4          2   a           8
5          5   a           8

2. 按索引連接

引數left_index=True或right_index=True

示例代碼:

# 按索引連接
df_obj1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
                        'data1' : np.random.randint(0,10,7)})
df_obj2 = pd.DataFrame({'data2' : np.random.randint(0,10,3)}, index=['a', 'b', 'd'])

print(pd.merge(df_obj1, df_obj2, left_on='key', right_index=True))

運行結果:

   data1 key  data2
0      3   b      6
1      4   b      6
6      8   b      6
2      6   a      0
4      3   a      0
5      0   a      0

2. 資料合并(pd.concat)

沿軸方向將多個物件合并到一起

1. NumPy的concat

np.concatenate

示例代碼:

import numpy as np
import pandas as pd

arr1 = np.random.randint(0, 10, (3, 4))
arr2 = np.random.randint(0, 10, (3, 4))

print(arr1)
print(arr2)

print(np.concatenate([arr1, arr2]))  # 默認axis=0,按行拼接
print(np.concatenate([arr1, arr2], axis=1))  # 按列拼接

運行結果:

# print(arr1)
[[3 3 0 8]
 [2 0 3 1]
 [4 8 8 2]]

# print(arr2)
[[6 8 7 3]
 [1 6 8 7]
 [1 4 7 1]]

# print(np.concatenate([arr1, arr2]))
 [[3 3 0 8]
 [2 0 3 1]
 [4 8 8 2]
 [6 8 7 3]
 [1 6 8 7]
 [1 4 7 1]]

# print(np.concatenate([arr1, arr2], axis=1)) 
[[3 3 0 8 6 8 7 3]
 [2 0 3 1 1 6 8 7]
 [4 8 8 2 1 4 7 1]]

2. pd.concat

  • 注意指定軸方向,默認axis=0

  • join指定合并方式,默認為outer

  • Series合并時查看行索引有無重復

df1 = pd.DataFrame(np.arange(6).reshape(3,2),index=list('abc'),columns=['one','two'])

df2 = pd.DataFrame(np.arange(4).reshape(2,2)+5,index=list('ac'),columns=['three','four'])

pd.concat([df1,df2]) #默認外連接,axis=0
    four    one    three    two
a    NaN        0.0    NaN        1.0
b    NaN        2.0    NaN        3.0
c    NaN        4.0    NaN        5.0
a    6.0        NaN    5.0        NaN
c    8.0        NaN    7.0        NaN

pd.concat([df1,df2],axis='columns') #指定axis=1連接
    one    two    three    four
a    0    1    5.0        6.0
b    2    3    NaN        NaN
c    4    5    7.0        8.0

#同樣我們也可以指定連接的方式為inner
pd.concat([df1,df2],axis=1,join='inner')

    one    two    three    four
a    0    1    5        6
c    4    5    7        8

7.3 重塑

1. stack

  • 將列索引旋轉為行索引,完成層級索引

  • DataFrame->Series

示例代碼:

import numpy as np
import pandas as pd

df_obj = pd.DataFrame(np.random.randint(0,10, (5,2)), columns=['data1', 'data2'])
print(df_obj)

stacked = df_obj.stack()
print(stacked)

運行結果:

# print(df_obj)
   data1  data2
0      7      9
1      7      8
2      8      9
3      4      1
4      1      2

# print(stacked)
0  data1    7
   data2    9
1  data1    7
   data2    8
2  data1    8
   data2    9
3  data1    4
   data2    1
4  data1    1
   data2    2
dtype: int64

2. unstack

  • 將層級索引展開

  • Series->DataFrame

  • 默認操作內層索引,即level=-1

示例代碼:

# 默認操作內層索引
print(stacked.unstack())

# 通過level指定操作索引的級別
print(stacked.unstack(level=0))

運行結果:

# print(stacked.unstack())
   data1  data2
0      7      9
1      7      8
2      8      9
3      4      1
4      1      2

# print(stacked.unstack(level=0))
       0  1  2  3  4
data1  7  7  8  4  1
data2  9  8  9  1  2

8. 資料分組聚合

  • 什么是分組聚合?如圖:

在這里插入圖片描述

  • groupby:(by=None,as_index=True)
  • by:根據什么進行分組,用于確定groupby的組

  • as_index:對于聚合輸出,回傳以組便簽為索引的物件,僅對DataFrame

df1 = pd.DataFrame({'fruit':['apple','banana','orange','apple','banana'],
                    'color':['red','yellow','yellow','cyan','cyan'],
                   'price':[8.5,6.8,5.6,7.8,6.4]})
#查看型別
type(df1.groupby('fruit'))
pandas.core.groupby.groupby.DataFrameGroupBy  #GruopBy物件,它是一個包含組名,和資料塊的2維元組序列,支持迭代
for name, group in df1.groupby('fruit'):
    print(name) #輸出組名
    apple
    banana
    orange

    print(group) # 輸出資料塊
       fruit color  price
    0  apple   red    8.5
    3  apple  cyan    7.8
       fruit   color  price
    1  banana  yellow    6.8
    4  banana    cyan    6.4
       fruit   color  price
    2  orange  yellow    5.6

    #輸出group型別  
    print(type(group))  #資料塊是dataframe型別
    <class 'pandas.core.frame.DataFrame'>
    <class 'pandas.core.frame.DataFrame'>
    <class 'pandas.core.frame.DataFrame'>

#選擇任意的資料塊
dict(list(df1.groupby('fruit')))['apple']  #取出apple組的資料塊
   fruit color  price
0  apple   red    8.5
3  apple  cyan    7.8

8.1 聚合

函式名描述
count分組中非NA值的數量
sum非NA值的和
mean非NA值的平均值
median非NA值的中位數
std, var標準差和方差
min, max非NA的最小值,最大值
prod非NA值的乘積
first, last非NA值的第一個,最后一個
#Groupby物件具有上表中的聚合方法

#根據fruit來求price的平均值
df1['price'].groupby(df1['fruit']).mean()
fruit
apple     8.15
banana    6.60
orange    5.60
Name: price, dtype: float64     
#或者
df1.groupby('fruit')['price'].mean()

# as_index=False(不把分組后的值作為索引,重新生成默認索引)
df1.groupby('fruit',as_index=False)['price'].mean()
    fruit    price
0    apple    8.15
1    banana    6.60
2    orange    5.60

"""
如果我現在有個需求,計算每種水果的差值,
1.上表中的聚合函式不能滿足于我們的需求,我們需要使用自定義的聚合函式
2.在分組物件中,使用我們自定義的聚合函式
"""
#定義一個計算差值的函式
def diff_value(arr):
    return arr.max() - arr.min()
#使用自定義聚合函式,我們需要將函式傳遞給agg或aggregate方法,我們使用自定義聚合函式時,會比我們表中的聚合函式慢的多,因為要進行函式呼叫,資料重新排列
df1.groupby('fruit')['price'].agg(diff_value)
fruit
apple     0.7
banana    0.4
orange    0.0
Name: price, dtype: float64

9. Pandas中的時間序列

時間序列(time series)資料是一種重要的結構化資料形式,

在多個時間點觀察或測量到的任何時間都可以形成一段時間序列,很多時間, 時間序列是固定頻率的, 也就是說, 資料點是根據某種規律定期出現的(比如每15秒…),

時間序列也可以是不定期的,時間序列資料的意義取決于具體的應用場景,

主要由以下幾種:

  • 時間戳(timestamp),特定的時刻,
  • 固定時期(period),如2007年1月或2010年全年,
  • 時間間隔(interval),由起始和結束時間戳表示,時期(period)可以被看做間隔(interval)的特例,

9.1 時間和日期資料型別及其工具

Python標準庫包含用于日期(date)和時間(time)資料的資料型別,而且還有日歷方面的功能,我們主要會用到datetimetime以及calendar模塊,

datetime.datetime(也可以簡寫為datetime)是用得最多的資料型別:

In [10]: from datetime import datetime

In [11]: now = datetime.now()

In [12]: now
Out[12]: datetime.datetime(2017, 9, 25, 14, 5, 52, 72973)

In [13]: now.year, now.month, now.day
Out[13]: (2017, 9, 25)

datetime以毫秒形式存盤日期和時間,timedelta表示兩個datetime物件之間的時間差:

In [14]: delta = datetime(2011, 1, 7) - datetime(2008, 6, 24, 8, 15)

In [15]: delta
Out[15]: datetime.timedelta(926, 56700)

In [16]: delta.days
Out[16]: 926

In [17]: delta.seconds
Out[17]: 56700

可以給datetime物件加上(或減去)一個或多個timedelta,這樣會產生一個新物件:

In [18]: from datetime import timedelta

In [19]: start = datetime(2011, 1, 7)

In [20]: start + timedelta(12)
Out[20]: datetime.datetime(2011, 1, 19, 0, 0)

In [21]: start - 2 * timedelta(12)
Out[21]: datetime.datetime(2010, 12, 14, 0, 0)

在這里插入圖片描述

9.2 字串和datetime的相互轉換

利用strstrftime方法(傳入一個格式化字串),datetime物件和pandas的Timestamp物件(稍后就會介紹)可以被格式化為字串:

In [22]: stamp = datetime(2011, 1, 3)

In [23]: str(stamp)
Out[23]: '2011-01-03 00:00:00'

In [24]: stamp.strftime('%Y-%m-%d')
Out[24]: '2011-01-03'

在這里插入圖片描述

datetime.strptime可以用這些格式化編碼將字串轉換為日期:

In [26]: datetime.strptime(value, '%Y-%m-%d')
Out[26]: datetime.datetime(2011, 1, 3, 0, 0)

In [27]: datestrs = ['7/6/2011', '8/6/2011']

In [28]: [datetime.strptime(x, '%m/%d/%Y') for x in datestrs]
Out[28]: 
[datetime.datetime(2011, 7, 6, 0, 0),
 datetime.datetime(2011, 8, 6, 0, 0)]

datetime.strptime是通過已知格式進行日期決議的最佳方式,但是每次都要撰寫格式定義是很麻煩的事情,尤其是對于一些常見的日期格式,

這種情況下,你可以用dateutil這個第三方包中的parser.parse方法(pandas中已經自動安裝好了):

In [29]: from dateutil.parser import parse

In [30]: parse('2011-01-03')
Out[30]: datetime.datetime(2011, 1, 3, 0, 0)

dateutil可以決議幾乎所有人類能夠理解的日期表示形式:

In [31]: parse('Jan 31, 1997 10:45 PM')
Out[31]: datetime.datetime(1997, 1, 31, 22, 45)

在國際通用的格式中,日出現在月的前面很普遍,傳入dayfirst=True即可解決這個問題:

In [32]: parse('6/12/2011', dayfirst=True)
Out[32]: datetime.datetime(2011, 12, 6, 0, 0)

Pandas通常是用于處理成組日期的,不管這些日期是DataFrame的軸索引還是列,to_datetime方法可以決議多種不同的日期表示形式,對標準日期格式(如ISO8601)的決議非常快:

In [33]: datestrs = ['2011-07-06 12:00:00', '2011-08-06 00:00:00']

In [34]: pd.to_datetime(datestrs)
Out[34]: DatetimeIndex(['2011-07-06 12:00:00', '2011-08-06 00:00:00'], dtype='datetime64[ns]', freq=None)

它還可以處理缺失值(None、空字串等):

In [35]: idx = pd.to_datetime(datestrs + [None])

In [36]: idx
Out[36]: DatetimeIndex(['2011-07-06 12:00:00', '2011-08-06 00:00:00', 'NaT'], dty
pe='datetime64[ns]', freq=None)

In [37]: idx[2]
Out[37]: NaT

In [38]: pd.isnull(idx)
Out[38]: array([False, False, True], dtype=bool)

NaT(Not a Time)是Pandas中時間戳資料的null值

時間序列基礎

pandas最基本的時間序列型別就是以時間戳(通常以Python字串或datatime物件表示)為索引的Series:

In [39]: from datetime import datetime

In [40]: dates = [datetime(2011, 1, 2), datetime(2011, 1, 5),
   ....:          datetime(2011, 1, 7), datetime(2011, 1, 8),
   ....:          datetime(2011, 1, 10), datetime(2011, 1, 12)]

In [41]: ts = pd.Series(np.random.randn(6), index=dates)

In [42]: ts
Out[42]: 
2011-01-02   -0.204708
2011-01-05    0.478943
2011-01-07   -0.519439
2011-01-08   -0.555730
2011-01-10    1.965781
2011-01-12    1.393406
dtype: float64

這些datetime物件實際上是被放在一個DatetimeIndex中的:

In [43]: ts.index
Out[43]: 
DatetimeIndex(['2011-01-02', '2011-01-05', '2011-01-07', '2011-01-08',
               '2011-01-10', '2011-01-12'],
              dtype='datetime64[ns]', freq=None)

跟其他Series一樣,不同索引的時間序列之間的算術運算會自動按日期對齊:

In [44]: ts + ts[::2]
Out[44]: 
2011-01-02   -0.409415
2011-01-05         NaN
2011-01-07   -1.038877
2011-01-08         NaN
2011-01-10    3.931561
2011-01-12         NaN
dtype: float64

ts[::2] 是每隔兩個取一個,

9.3 索引、選取、子集構造

當你根據標簽索引選取資料時,時間序列和其它的pandas.Series很像:

In [48]: stamp = ts.index[2]

In [49]: ts[stamp]
Out[49]: -0.51943871505673811

還有一種更為方便的用法:傳入一個可以被解釋為日期的字串:

In [50]: ts['1/10/2011']
Out[50]: 1.9657805725027142

In [51]: ts['20110110']
Out[51]: 1.9657805725027142

9.4 日期的范圍、頻率以及移動

Pandas中的原生時間序列一般被認為是不規則的,也就是說,它們沒有固定的頻率,對于大部分應用程式而言,這是無所謂的,但是,它常常需要以某種相對固定的頻率進行分析,比如每日、每月、每15分鐘等(這樣自然會在時間序列中引入缺失值),

幸運的是,pandas有一整套標準時間序列頻率以及用于重采樣、頻率推斷、生成固定頻率日期范圍的工具

例如,我們可以將之前那個時間序列轉換為一個具有固定頻率(每日)的時間序列,只需呼叫resample即可:

In [72]: ts
Out[72]: 
2011-01-02   -0.204708
2011-01-05    0.478943
2011-01-07   -0.519439
2011-01-08   -0.555730
2011-01-10    1.965781
2011-01-12    1.393406
dtype: float64

In [73]: resampler = ts.resample('D')

字串“D”是每天的意思,

頻率的轉換(或重采樣)是一個比較大的主題,這里,我將告訴你如何使用基本的頻率和它的倍數,

生成日期范圍

雖然我之前用的時候沒有明說,但你可能已經猜到pandas.date_range可用于根據指定的頻率生成指定長度的 DatetimeIndex

In [74]: index = pd.date_range('2012-04-01', '2012-06-01')

In [75]: index
Out[75]: 
DatetimeIndex(['2012-04-01', '2012-04-02', '2012-04-03', '2012-04-04',
               '2012-04-05', '2012-04-06', '2012-04-07', '2012-04-08',
               '2012-04-09', '2012-04-10', '2012-04-11', '2012-04-12',
               '2012-04-13', '2012-04-14', '2012-04-15', '2012-04-16',
               '2012-04-17', '2012-04-18', '2012-04-19', '2012-04-20',
               '2012-04-21', '2012-04-22', '2012-04-23', '2012-04-24',
               '2012-04-25', '2012-04-26', '2012-04-27', '2012-04-28',
               '2012-04-29', '2012-04-30', '2012-05-01', '2012-05-02',
               '2012-05-03', '2012-05-04', '2012-05-05', '2012-05-06',
               '2012-05-07', '2012-05-08', '2012-05-09', '2012-05-10',
               '2012-05-11', '2012-05-12', '2012-05-13', '2012-05-14',
               '2012-05-15', '2012-05-16', '2012-05-17', '2012-05-18',
               '2012-05-19', '2012-05-20', '2012-05-21', '2012-05-22',
               '2012-05-23', '2012-05-24', '2012-05-25', '2012-05-26',
               '2012-05-27', '2012-05-28', '2012-05-29', '2012-05-30',
               '2012-05-31', '2012-06-01'],
              dtype='datetime64[ns]', freq='D')

默認情況下,date_range會產生按天計算的時間點,如果只傳入起始或結束日期,那就還得傳入一個表示一段時間的數字:

In [76]: pd.date_range(start='2012-04-01', periods=20)
Out[76]: 
DatetimeIndex(['2012-04-01', '2012-04-02', '2012-04-03', '2012-04-04',
               '2012-04-05', '2012-04-06', '2012-04-07', '2012-04-08',
               '2012-04-09', '2012-04-10', '2012-04-11', '2012-04-12',
               '2012-04-13', '2012-04-14', '2012-04-15', '2012-04-16',
               '2012-04-17', '2012-04-18', '2012-04-19', '2012-04-20'],
              dtype='datetime64[ns]', freq='D')

In [77]: pd.date_range(end='2012-06-01', periods=20)
Out[77]: 
DatetimeIndex(['2012-05-13', '2012-05-14', '2012-05-15', '2012-05-16',
               '2012-05-17', '2012-05-18', '2012-05-19', '2012-05-20',
               '2012-05-21', '2012-05-22', '2012-05-23', '2012-05-24',
               '2012-05-25', '2012-05-26', '2012-05-27','2012-05-28',
               '2012-05-29', '2012-05-30', '2012-05-31', '2012-06-01'],
              dtype='datetime64[ns]', freq='D')

起始和結束日期定義了日期索引的嚴格邊界

例如,如果你想要生成一個由每月最后一個作業日組成的日期索引,可以傳入"BM"頻率(表示business end of month),這樣就只會包含時間間隔內(或剛好在邊界上的)符合頻率要求的日期:

In [78]: pd.date_range('2000-01-01', '2000-12-01', freq='BM')
Out[78]: 
DatetimeIndex(['2000-01-31', '2000-02-29', '2000-03-31', '2000-04-28',
               '2000-05-31', '2000-06-30', '2000-07-31', '2000-08-31',
               '2000-09-29', '2000-10-31', '2000-11-30'],
              dtype='datetime64[ns]', freq='BM')

在這里插入圖片描述

重采樣及頻率轉換

重采樣(resampling)指的是將時間序列從一個頻率轉換到另一個頻率的處理程序

將高頻率資料聚合到低頻率稱為降采樣(downsampling),而將低頻率資料轉換到高頻率則稱為升采樣(upsampling),并不是所有的重采樣都能被劃分到這兩個大類中,

例如,將W-WED(每周三)轉換為W-FRI既不是降采樣也不是升采樣,

Pandas物件都帶有一個resample方法,它是各種頻率轉換作業的主力函式,resample有一個類似于groupby的API,呼叫resample可以分組資料,然后會呼叫一個聚合函式:

In [208]: rng = pd.date_range('2000-01-01', periods=100, freq='D')

In [209]: ts = pd.Series(np.random.randn(len(rng)), index=rng)

In [210]: ts
Out[210]: 
2000-01-01    0.631634
2000-01-02   -1.594313
2000-01-03   -1.519937
2000-01-04    1.108752
2000-01-05    1.255853
2000-01-06   -0.024330
2000-01-07   -2.047939
2000-01-08   -0.272657
2000-01-09   -1.692615
2000-01-10    1.423830
                ...   
2000-03-31   -0.007852
2000-04-01   -1.638806
2000-04-02    1.401227
2000-04-03    1.758539
2000-04-04    0.628932
2000-04-05   -0.423776
2000-04-06    0.789740
2000-04-07    0.937568
2000-04-08   -2.253294
2000-04-09   -1.772919
Freq: D, Length: 100, dtype: float64

In [211]: ts.resample('M').mean()
Out[211]: 
2000-01-31   -0.165893
2000-02-29    0.078606
2000-03-31    0.223811
2000-04-30   -0.063643
Freq: M, dtype: float64

In [212]: ts.resample('M', kind='period').mean()
Out[212]: 
2000-01   -0.165893
2000-02    0.078606
2000-03    0.223811
2000-04   -0.063643
Freq: M, dtype: float64

resample是一個靈活高效的方法,可用于處理非常大的時間序列,

在這里插入圖片描述


加油!

感謝!

努力!

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/317786.html

標籤:AI

上一篇:Python將彩色圖轉換為灰度圖

下一篇:關于cv2.connectedComponentsWithStats使用說明

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more