小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Python學習筆記

 hoezigin 2019-03-22

目錄

什么是Pandas?

Pandas常用操作

pandas之Series創(chuàng)建

pandas之Series的索引和值

pandas之讀取外部數(shù)據(jù)

pandas之DataFrame

pandas之取行或者列

pandas之loc

pandas之iloc

pandas之布爾索引

pandas之字符串方法

缺失數(shù)據(jù)的處理

pandas常用統(tǒng)計方法

數(shù)據(jù)合并之join

數(shù)據(jù)合并之merge

分組和聚合

索引和復合索引

Series復合索引

DataFrame復合索引

時間序列

生成一段時間范圍

關于頻率的更多縮寫

在DataFrame中使用時間序列

pandas重采樣

PeriodIndex

Pandas的數(shù)據(jù)結構

Series

DataFrame

Pandas的索引操作

索引對象Index

Series索引

DataFrame索引

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

Pandas的對齊運算

Series的對齊運算

DataFrame的對齊運算

填充未對齊的數(shù)據(jù)進行運算

Pandas的函數(shù)應用

apply 和 applymap

排序

處理缺失數(shù)據(jù)

層級索引(hierarchical indexing)

MultiIndex索引對象

選取子集

交換分層順序

交換并排序分層

Pandas統(tǒng)計計算和描述

常用的統(tǒng)計計算

常用的統(tǒng)計描述

常用的統(tǒng)計描述方法:

Pandas分組與聚合

分組 (groupby)

一、GroupBy對象:DataFrameGroupBy,SeriesGroupBy

二、GroupBy對象支持迭代操作

聚合 (aggregation)

數(shù)據(jù)的分組運算

groupby.apply(func)

數(shù)據(jù)清洗

數(shù)據(jù)連接(pd.merge)

數(shù)據(jù)合并(pd.concat)

數(shù)據(jù)重構

數(shù)據(jù)轉換

一、 處理重復數(shù)據(jù)

二、數(shù)據(jù)替換

聚類模型:K-Means

K-Means算法

算法思想:

算法描述:

優(yōu)缺點:

全球食品數(shù)據(jù)分析


什么是Pandas?

Pandas的名稱來自于面板數(shù)據(jù)(panel data)和Python數(shù)據(jù)分析(data analysis)。

Pandas是一個強大的分析結構化數(shù)據(jù)的工具集,基于NumPy構建,提供了 高級數(shù)據(jù)結構 和 數(shù)據(jù)操作工具,它是使Python成為強大而高效的數(shù)據(jù)分析環(huán)境的重要因素之一。

  • 一個強大的分析和操作大型結構化數(shù)據(jù)集所需的工具集

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

  • 提供了大量能夠快速便捷地處理數(shù)據(jù)的函數(shù)和方法

  • 應用于數(shù)據(jù)挖掘,數(shù)據(jù)分析

  • 提供數(shù)據(jù)清洗功能

http://pandas.

Pandas常用操作

pandas之Series創(chuàng)建

pandas之Series創(chuàng)建

pandas之Series的索引和值

pandas之讀取外部數(shù)據(jù)

數(shù)據(jù)存在csv中,直接使用pd. read_csv即可

對于數(shù)據(jù)庫比如mysql或者mongodb中數(shù)據(jù)pd.read_sql(sql_sentence,connection)

pandas之DataFrame

DataFrame對象既有行索引,又有列索引

行索引,表明不同行,橫向索引,叫index,0軸,axis=0

列索引,表名不同列,縱向索引,叫columns,1軸,axis=1

df.sort_values(by="Count_AnimalName",ascending=False) #排序

pandas之取行或者列

df_sorted = df.sort_values(by="Count_AnimalName")

df_sorted[:100]

那么問題來了:

我們具體要選擇某一列該怎么選擇呢?df[" Count_AnimalName "]

我們要同時選擇行和列改怎么辦?df[:100][" Count_AnimalName "]

pandas之loc

還有更多的經過pandas優(yōu)化過的選擇方式:

1.df.loc 通過標簽索引行數(shù)據(jù)

2.df.iloc 通過位置獲取行數(shù)據(jù)

pandas之iloc

賦值更改數(shù)據(jù)的過程:

pandas之布爾索引

pandas之字符串方法

缺失數(shù)據(jù)的處理

我們的數(shù)據(jù)缺失通常有兩種情況:

一種就是空,None等,在pandas是NaN(和np.nan一樣)

另一種是我們讓其為0,藍色框中

對于NaN的數(shù)據(jù),在numpy中我們是如何處理的?

在pandas中我們處理起來非常容易

 

判斷數(shù)據(jù)是否為NaN:pd.isnull(df),pd.notnull(df)

 

處理方式1:刪除NaN所在的行列dropna (axis=0, how='any', inplace=False)

處理方式2:填充數(shù)據(jù),t.fillna(t.mean()),t.fiallna(t.median()),t.fillna(0)

 

處理為0的數(shù)據(jù):t[t==0]=np.nan

當然并不是每次為0的數(shù)據(jù)都需要處理

計算平均值等情況,nan是不參與計算的,但是0會

pandas常用統(tǒng)計方法

數(shù)據(jù)合并之join

join:默認情況下他是把行索引相同的數(shù)據(jù)合并到一起

數(shù)據(jù)合并之merge

默認的合并方式inner,并集

merge outer,交集,NaN補全

merge left,左邊為準,NaN補全

merge right,右邊為準,NaN補全

分組和聚合

在pandas中類似的分組的操作我們有很簡單的方式來完成

df.groupby(by="columns_name")

那么問題來了,調用groupby方法之后返回的是什么內容?

grouped = df.groupby(by="columns_name")

grouped是一個DataFrameGroupBy對象,是可迭代的

grouped中的每一個元素是一個元組

元組里面是(索引(分組的值),分組之后的DataFrame)

那么,回到之前的問題:

要統(tǒng)計美國和中國的星巴克的數(shù)量,我們應該怎么做?

分組之后的每個DataFrame的長度?

長度是一個思路,但是我們有更多的方法(聚合方法)來解決這個問題

DataFrameGroupBy對象有很多經過優(yōu)化的方法

如果我們需要對國家和省份進行分組統(tǒng)計,應該怎么操作呢?

grouped = df.groupby(by=[df["Country"],df["State/Province"]])

很多時候我們只希望對獲取分組之后的某一部分數(shù)據(jù),或者說我們只希望對某幾列數(shù)據(jù)進行分組,這個時候我們應該怎么辦呢?

獲取分組之后的某一部分數(shù)據(jù):

 df.groupby(by=["Country","State/Province"])["Country"].count()

對某幾列數(shù)據(jù)進行分組:

 df["Country"].groupby(by=[df["Country"],df["State/Province"]]).count()

觀察結果,由于只選擇了一列數(shù)據(jù),所以結果是一個Series類型

如果我想返回一個DataFrame類型呢?

t1 = df[["Country"]].groupby(by=[df["Country"],df["State/Province"]]).count()
t2 = df.groupby(by=["Country","State/Province"])[["Country"]].count()

以上的兩條命令結果一樣

和之前的結果的區(qū)別在于當前返回的是一個DataFrame類型

那么問題來了:

和之前使用一個分組條件相比,當前的返回結果的前兩列是什么?

索引和復合索引

簡單的索引操作:

·獲取index:df.index

·指定index :df.index = ['x','y']

·重新設置index : df.reindex(list("abcedf"))

·指定某一列作為index :df.set_index("Country",drop=False)

·返回index的唯一值:df.set_index("Country").index.unique()

假設a為一個DataFrame,那么當a.set_index(["c","d"])即設置兩個索引的時候是什么樣子的結果呢?

a = pd.DataFrame({'a': range(7),'b': range(7, 0, -1),'c': ['one','one','one','two','two','two', 'two'],'d': list("hjklmno")})

Series復合索引

DataFrame復合索引

時間序列

生成一段時間范圍

pd.date_range(start=None, end=None, periods=None, freq='D')

start和end以及freq配合能夠生成startend范圍內以頻率freq的一組時間索引

start和periods以及freq配合能夠生成從start開始的頻率為freq的periods時間索引

關于頻率的更多縮寫

在DataFrame中使用時間序列

index=pd.date_range("20170101",periods=10)

df = pd.DataFrame(np.random.rand(10),index=index)

回到最開始的911數(shù)據(jù)的案例中,我們可以使用pandas提供的方法把時間字符串轉化為時間序列

df["timeStamp"] = pd.to_datetime(df["timeStamp"],format="")

format參數(shù)大部分情況下可以不用寫,但是對于pandas無法格式化的時間字符串,我們可以使用該參數(shù),比如包含中文

那么問題來了:

我們現(xiàn)在要統(tǒng)計每個月或者每個季度的次數(shù)怎么辦呢?

pandas重采樣

重采樣:指的是將時間序列從一個頻率轉化為另一個頻率進行處理的過程,將高頻率數(shù)據(jù)轉化為低頻率數(shù)據(jù)為降采樣,低頻率轉化為高頻率為升采樣

pandas提供了一個resample的方法來幫助我們實現(xiàn)頻率轉化

PeriodIndex

之前所學習的DatetimeIndex可以理解為時間戳

那么現(xiàn)在我們要學習的PeriodIndex可以理解為時間段

periods = pd.PeriodIndex(year=data["year"],month=data["month"],day=data["day"],hour=data["hour"],freq="H")

那么如果給這個時間段降采樣呢?
data = df.set_index(periods).resample("10D").mean()

Pandas的數(shù)據(jù)結構

import pandas as pd

Pandas有兩個最主要也是最重要的數(shù)據(jù)結構: Series 和 DataFrame

Series

Series是一種類似于一維數(shù)組的 對象,由一組數(shù)據(jù)(各種NumPy數(shù)據(jù)類型)以及一組與之對應的索引(數(shù)據(jù)標簽)組成。

  • 類似一維數(shù)組的對象
  • 由數(shù)據(jù)和索引組成
    • 索引(index)在左,數(shù)據(jù)(values)在右
    • 索引是自動創(chuàng)建的

1. 通過list構建Series

ser_obj = pd.Series(range(10))

示例代碼:

  1. # 通過list構建Series
  2. ser_obj = pd.Series(range(10, 20))
  3. print(ser_obj.head(3))
  4. print(ser_obj)
  5. print(type(ser_obj))

運行結果:

  1. 0 10
  2. 1 11
  3. 2 12
  4. dtype: int64
  5. 0 10
  6. 1 11
  7. 2 12
  8. 3 13
  9. 4 14
  10. 5 15
  11. 6 16
  12. 7 17
  13. 8 18
  14. 9 19
  15. dtype: int64
  16. <class 'pandas.core.series.Series'>

2. 獲取數(shù)據(jù)和索引

ser_obj.index 和 ser_obj.values

示例代碼:

  1. # 獲取數(shù)據(jù)
  2. print(ser_obj.values)
  3. # 獲取索引
  4. print(ser_obj.index)

運行結果:

  1. [10 11 12 13 14 15 16 17 18 19]
  2. RangeIndex(start=0, stop=10, step=1)

3. 通過索引獲取數(shù)據(jù)

ser_obj[idx]

示例代碼:

  1. #通過索引獲取數(shù)據(jù)
  2. print(ser_obj[0])
  3. print(ser_obj[8])

運行結果:

  1. 10
  2. 18

4. 索引與數(shù)據(jù)的對應關系不被運算結果影響

示例代碼:

  1. # 索引與數(shù)據(jù)的對應關系不被運算結果影響
  2. print(ser_obj * 2)
  3. print(ser_obj > 15)

運行結果:

  1. 0 20
  2. 1 22
  3. 2 24
  4. 3 26
  5. 4 28
  6. 5 30
  7. 6 32
  8. 7 34
  9. 8 36
  10. 9 38
  11. dtype: int64
  12. 0 False
  13. 1 False
  14. 2 False
  15. 3 False
  16. 4 False
  17. 5 False
  18. 6 True
  19. 7 True
  20. 8 True
  21. 9 True
  22. dtype: bool

5. 通過dict構建Series

示例代碼:

  1. # 通過dict構建Series
  2. year_data = {2001: 17.8, 2002: 20.1, 2003: 16.5}
  3. ser_obj2 = pd.Series(year_data)
  4. print(ser_obj2.head())
  5. print(ser_obj2.index)

運行結果:

  1. 2001 17.8
  2. 2002 20.1
  3. 2003 16.5
  4. dtype: float64
  5. Int64Index([2001, 2002, 2003], dtype='int64')

name屬性

對象名:ser_obj.name

對象索引名:ser_obj.index.name

示例代碼:

  1. # name屬性
  2. ser_obj2.name = 'temp'
  3. ser_obj2.index.name = 'year'
  4. print(ser_obj2.head())

運行結果:

  1. year
  2. 2001 17.8
  3. 2002 20.1
  4. 2003 16.5
  5. Name: temp, dtype: float64


DataFrame

DataFrame是一個表格型的數(shù)據(jù)結構,它含有一組有序的列,每列可以是不同類型的值。DataFrame既有行索引也有列索引,它可以被看做是由Series組成的字典(共用同一個索引),數(shù)據(jù)是以二維結構存放的。

  • 類似多維數(shù)組/表格數(shù)據(jù) (如,excel, R中的data.frame)
  • 每列數(shù)據(jù)可以是不同的類型
  • 索引包括列索引和行索引

1. 通過ndarray構建DataFrame

示例代碼:

  1. import numpy as np
  2. # 通過ndarray構建DataFrame
  3. array = np.random.randn(5,4)
  4. print(array)
  5. df_obj = pd.DataFrame(array)
  6. print(df_obj.head())

運行結果:

  1. [[ 0.83500594 -1.49290138 -0.53120106 -0.11313932]
  2. [ 0.64629762 -0.36779941 0.08011084 0.60080495]
  3. [-1.23458522 0.33409674 -0.58778195 -0.73610573]
  4. [-1.47651414 0.99400187 0.21001995 -0.90515656]
  5. [ 0.56669419 1.38238348 -0.49099007 1.94484598]]
  6. 0 1 2 3
  7. 0 0.835006 -1.492901 -0.531201 -0.113139
  8. 1 0.646298 -0.367799 0.080111 0.600805
  9. 2 -1.234585 0.334097 -0.587782 -0.736106
  10. 3 -1.476514 0.994002 0.210020 -0.905157
  11. 4 0.566694 1.382383 -0.490990 1.944846

2. 通過dict構建DataFrame

示例代碼:

  1. # 通過dict構建DataFrame
  2. dict_data = {'A': 1,
  3. 'B': pd.Timestamp('20170426'),
  4. 'C': pd.Series(1, index=list(range(4)),dtype='float32'),
  5. 'D': np.array([3] * 4,dtype='int32'),
  6. 'E': ["Python","Java","C++","C"],
  7. 'F': 'ITCast' }
  8. #print dict_data
  9. df_obj2 = pd.DataFrame(dict_data)
  10. print(df_obj2)

運行結果:

  1. A B C D E F
  2. 0 1 2017-04-26 1.0 3 Python ITCast
  3. 1 1 2017-04-26 1.0 3 Java ITCast
  4. 2 1 2017-04-26 1.0 3 C++ ITCast
  5. 3 1 2017-04-26 1.0 3 C ITCast

3. 通過列索引獲取列數(shù)據(jù)(Series類型)

df_obj[col_idx] 或 df_obj.col_idx

示例代碼:

  1. # 通過列索引獲取列數(shù)據(jù)
  2. print(df_obj2['A'])
  3. print(type(df_obj2['A']))
  4. print(df_obj2.A)

運行結果:

  1. 0 1.0
  2. 1 1.0
  3. 2 1.0
  4. 3 1.0
  5. Name: A, dtype: float64
  6. <class 'pandas.core.series.Series'>
  7. 0 1.0
  8. 1 1.0
  9. 2 1.0
  10. 3 1.0
  11. Name: A, dtype: float64

4. 增加列數(shù)據(jù)

df_obj[new_col_idx] = data

類似Python的 dict添加key-value

示例代碼:

  1. # 增加列
  2. df_obj2['G'] = df_obj2['D'] + 4
  3. print(df_obj2.head())

運行結果:

  1. A B C D E F G
  2. 0 1.0 2017-01-02 1.0 3 Python ITCast 7
  3. 1 1.0 2017-01-02 1.0 3 Java ITCast 7
  4. 2 1.0 2017-01-02 1.0 3 C++ ITCast 7
  5. 3 1.0 2017-01-02 1.0 3 C ITCast 7

5. 刪除列

del df_obj[col_idx]

示例代碼:

  1. # 刪除列
  2. del(df_obj2['G'] )
  3. print(df_obj2.head())

運行結果:

  1. A B C D E F
  2. 0 1.0 2017-01-02 1.0 3 Python ITCast
  3. 1 1.0 2017-01-02 1.0 3 Java ITCast
  4. 2 1.0 2017-01-02 1.0 3 C++ ITCast
  5. 3 1.0 2017-01-02 1.0 3 C ITCast

Pandas的索引操作

索引對象Index

1. Series和DataFrame中的索引都是Index對象

示例代碼:

  1. print(type(ser_obj.index))
  2. print(type(df_obj2.index))
  3. print(df_obj2.index)

運行結果:

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

2. 索引對象不可變,保證了數(shù)據(jù)的安全

示例代碼:

  1. # 索引對象不可變
  2. df_obj2.index[0] = 2

運行結果:

  1. ---------------------------------------------------------------------------
  2. TypeError Traceback (most recent call last)
  3. <ipython-input-23-7f40a356d7d1> in <module>()
  4. 1 # 索引對象不可變
  5. ----> 2 df_obj2.index[0] = 2
  6. /Users/Power/anaconda/lib/python3.6/site-packages/pandas/indexes/base.py in __setitem__(self, key, value)
  7. 1402
  8. 1403 def __setitem__(self, key, value):
  9. -> 1404 raise TypeError("Index does not support mutable operations")
  10. 1405
  11. 1406 def __getitem__(self, key):
  12. TypeError: Index does not support mutable operations

常見的Index種類

  • Index,索引
  • Int64Index,整數(shù)索引
  • MultiIndex,層級索引
  • DatetimeIndex,時間戳類型

Series索引

1. index 指定行索引名

示例代碼:

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

運行結果:

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

2. 行索引

ser_obj[‘label’], ser_obj[pos]

示例代碼:

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

運行結果:

  1. 1
  2. 2

3. 切片索引

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

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

示例代碼:

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

運行結果:

  1. b 1
  2. c 2
  3. dtype: int64
  4. b 1
  5. c 2
  6. d 3
  7. dtype: int64

4. 不連續(xù)索引

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

示例代碼:

  1. # 不連續(xù)索引
  2. print(ser_obj[[0, 2, 4]])
  3. print(ser_obj[['a', 'e']])

運行結果:

  1. a 0
  2. c 2
  3. e 4
  4. dtype: int64
  5. a 0
  6. e 4
  7. dtype: int64

5. 布爾索引

示例代碼:

  1. # 布爾索引
  2. ser_bool = ser_obj > 2
  3. print(ser_bool)
  4. print(ser_obj[ser_bool])
  5. print(ser_obj[ser_obj > 2])

運行結果:

  1. a False
  2. b False
  3. c False
  4. d True
  5. e True
  6. dtype: bool
  7. d 3
  8. e 4
  9. dtype: int64
  10. d 3
  11. e 4
  12. dtype: int64

DataFrame索引

1. columns 指定列索引名

示例代碼:

  1. import numpy as np
  2. df_obj = pd.DataFrame(np.random.randn(5,4), columns = ['a', 'b', 'c', 'd'])
  3. print(df_obj.head())

運行結果:

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

2. 列索引

df_obj[[‘label’]]

示例代碼:

  1. # 列索引
  2. print(df_obj['a']) # 返回Series類型
  3. print(df_obj[[0]]) # 返回DataFrame類型
  4. print(type(df_obj[[0]])) # 返回DataFrame類型

運行結果:

  1. 0 -0.241678
  2. 1 -0.526918
  3. 2 -1.074163
  4. 3 -0.716816
  5. 4 0.368212
  6. Name: a, dtype: float64
  7. <class 'pandas.core.frame.DataFrame'>

3. 不連續(xù)索引

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

示例代碼:

  1. # 不連續(xù)索引
  2. print(df_obj[['a','c']])
  3. print(df_obj[[1, 3]])

運行結果:

  1. a c
  2. 0 -0.241678 0.843546
  3. 1 -0.526918 1.124420
  4. 2 -1.074163 -0.309822
  5. 3 -0.716816 -2.123637
  6. 4 0.368212 0.064703
  7. b d
  8. 0 0.621589 -0.383105
  9. 1 -0.485325 -0.653144
  10. 2 0.939324 -0.209149
  11. 3 1.844654 -1.323484
  12. 4 -0.910324 0.486016

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

Pandas的高級索引有3種

1. loc 標簽索引

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

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

示例代碼:

  1. # 標簽索引 loc
  2. # Series
  3. print(ser_obj['b':'d'])
  4. print(ser_obj.loc['b':'d'])
  5. # DataFrame
  6. print(df_obj['a'])
  7. # 第一個參數(shù)索引行,第二個參數(shù)是列
  8. print(df_obj.loc[0:2, 'a'])

運行結果:

  1. b 1
  2. c 2
  3. d 3
  4. dtype: int64
  5. b 1
  6. c 2
  7. d 3
  8. dtype: int64
  9. 0 -0.241678
  10. 1 -0.526918
  11. 2 -1.074163
  12. 3 -0.716816
  13. 4 0.368212
  14. Name: a, dtype: float64
  15. 0 -0.241678
  16. 1 -0.526918
  17. 2 -1.074163
  18. Name: a, dtype: float64

2. iloc 位置索引

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

示例代碼:

  1. # 整型位置索引 iloc
  2. # Series
  3. print(ser_obj[1:3])
  4. print(ser_obj.iloc[1:3])
  5. # DataFrame
  6. print(df_obj.iloc[0:2, 0]) # 注意和df_obj.loc[0:2, 'a']的區(qū)別

運行結果:

  1. b 1
  2. c 2
  3. dtype: int64
  4. b 1
  5. c 2
  6. dtype: int64
  7. 0 -0.241678
  8. 1 -0.526918
  9. Name: a, dtype: float64

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

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

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

示例代碼:

  1. # 混合索引 ix
  2. # Series
  3. print(ser_obj.ix[1:3])
  4. print(ser_obj.ix['b':'c'])
  5. # DataFrame
  6. print(df_obj.loc[0:2, 'a'])
  7. print(df_obj.ix[0:2, 0])

運行結果:

  1. b 1
  2. c 2
  3. dtype: int64
  4. b 1
  5. c 2
  6. dtype: int64
  7. 0 -0.241678
  8. 1 -0.526918
  9. 2 -1.074163
  10. Name: a, dtype: float64

注意

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

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

Pandas的對齊運算

是數(shù)據(jù)清洗的重要過程,可以按索引對齊進行運算,如果沒對齊的位置則補NaN,最后也可以填充NaN

Series的對齊運算

1. Series 按行、索引對齊

示例代碼:

  1. s1 = pd.Series(range(10, 20), index = range(10))
  2. s2 = pd.Series(range(20, 25), index = range(5))
  3. print('s1: ' )
  4. print(s1)
  5. print('')
  6. print('s2: ')
  7. print(s2)

運行結果:

  1. s1:
  2. 0 10
  3. 1 11
  4. 2 12
  5. 3 13
  6. 4 14
  7. 5 15
  8. 6 16
  9. 7 17
  10. 8 18
  11. 9 19
  12. dtype: int64
  13. s2:
  14. 0 20
  15. 1 21
  16. 2 22
  17. 3 23
  18. 4 24
  19. dtype: int64

2. Series的對齊運算

示例代碼:

  1. # Series 對齊運算
  2. s1 + s2

運行結果:

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

DataFrame的對齊運算

1. DataFrame按行、列索引對齊

示例代碼:

  1. df1 = pd.DataFrame(np.ones((2,2)), columns = ['a', 'b'])
  2. df2 = pd.DataFrame(np.ones((3,3)), columns = ['a', 'b', 'c'])
  3. print('df1: ')
  4. print(df1)
  5. print('')
  6. print('df2: ')
  7. print(df2)

運行結果:

  1. df1:
  2. a b
  3. 0 1.0 1.0
  4. 1 1.0 1.0
  5. df2:
  6. a b c
  7. 0 1.0 1.0 1.0
  8. 1 1.0 1.0 1.0
  9. 2 1.0 1.0 1.0

2. DataFrame的對齊運算

示例代碼:

  1. # DataFrame對齊操作
  2. df1 + df2

運行結果:

  1. a b c
  2. 0 2.0 2.0 NaN
  3. 1 2.0 2.0 NaN
  4. 2 NaN NaN NaN

填充未對齊的數(shù)據(jù)進行運算

1. fill_value

使用addsubdivmul的同時,

通過fill_value指定填充值,未對齊的數(shù)據(jù)將和填充值做運算

示例代碼:

  1. print(s1)
  2. print(s2)
  3. s1.add(s2, fill_value = -1)
  4. print(df1)
  5. print(df2)
  6. df1.sub(df2, fill_value = 2.)

運行結果:

  1. # print(s1)
  2. 0 10
  3. 1 11
  4. 2 12
  5. 3 13
  6. 4 14
  7. 5 15
  8. 6 16
  9. 7 17
  10. 8 18
  11. 9 19
  12. dtype: int64
  13. # print(s2)
  14. 0 20
  15. 1 21
  16. 2 22
  17. 3 23
  18. 4 24
  19. dtype: int64
  20. # s1.add(s2, fill_value = -1)
  21. 0 30.0
  22. 1 32.0
  23. 2 34.0
  24. 3 36.0
  25. 4 38.0
  26. 5 14.0
  27. 6 15.0
  28. 7 16.0
  29. 8 17.0
  30. 9 18.0
  31. dtype: float64
  32. # print(df1)
  33. a b
  34. 0 1.0 1.0
  35. 1 1.0 1.0
  36. # print(df2)
  37. a b c
  38. 0 1.0 1.0 1.0
  39. 1 1.0 1.0 1.0
  40. 2 1.0 1.0 1.0
  41. # df1.sub(df2, fill_value = 2.)
  42. a b c
  43. 0 0.0 0.0 1.0
  44. 1 0.0 0.0 1.0
  45. 2 1.0 1.0 1.0

Pandas的函數(shù)應用

apply 和 applymap

1. 可直接使用NumPy的函數(shù)

示例代碼:

  1. # Numpy ufunc 函數(shù)
  2. df = pd.DataFrame(np.random.randn(5,4) - 1)
  3. print(df)
  4. print(np.abs(df))

運行結果:

  1. 0 1 2 3
  2. 0 -0.062413 0.844813 -1.853721 -1.980717
  3. 1 -0.539628 -1.975173 -0.856597 -2.612406
  4. 2 -1.277081 -1.088457 -0.152189 0.530325
  5. 3 -1.356578 -1.996441 0.368822 -2.211478
  6. 4 -0.562777 0.518648 -2.007223 0.059411
  7. 0 1 2 3
  8. 0 0.062413 0.844813 1.853721 1.980717
  9. 1 0.539628 1.975173 0.856597 2.612406
  10. 2 1.277081 1.088457 0.152189 0.530325
  11. 3 1.356578 1.996441 0.368822 2.211478
  12. 4 0.562777 0.518648 2.007223 0.059411

2. 通過apply將函數(shù)應用到列或行上

示例代碼:

  1. # 使用apply應用行或列數(shù)據(jù)
  2. #f = lambda x : x.max()
  3. print(df.apply(lambda x : x.max()))

運行結果:

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

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

示例代碼:

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

運行結果:

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

3. 通過applymap將函數(shù)應用到每個數(shù)據(jù)上

示例代碼:

  1. # 使用applymap應用到每個數(shù)據(jù)
  2. f2 = lambda x : '%.2f' % x
  3. print(df.applymap(f2))

運行結果:

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

排序

1. 索引排序

sort_index()

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

示例代碼:

  1. # Series
  2. s4 = pd.Series(range(10, 15), index = np.random.randint(5, size=5))
  3. print(s4)
  4. # 索引排序
  5. s4.sort_index() # 0 0 1 3 3

運行結果:

  1. 0 10
  2. 3 11
  3. 1 12
  4. 3 13
  5. 0 14
  6. dtype: int64
  7. 0 10
  8. 0 14
  9. 1 12
  10. 3 11
  11. 3 13
  12. dtype: int64

對DataFrame操作時注意軸方向

示例代碼:

  1. # DataFrame
  2. df4 = pd.DataFrame(np.random.randn(3, 5),
  3. index=np.random.randint(3, size=3),
  4. columns=np.random.randint(5, size=5))
  5. print(df4)
  6. df4_isort = df4.sort_index(axis=1, ascending=False)
  7. print(df4_isort) # 4 2 1 1 0

運行結果:

  1. 1 4 0 1 2
  2. 2 -0.416686 -0.161256 0.088802 -0.004294 1.164138
  3. 1 -0.671914 0.531256 0.303222 -0.509493 -0.342573
  4. 1 1.988321 -0.466987 2.787891 -1.105912 0.889082
  5. 4 2 1 1 0
  6. 2 -0.161256 1.164138 -0.416686 -0.004294 0.088802
  7. 1 0.531256 -0.342573 -0.671914 -0.509493 0.303222
  8. 1 -0.466987 0.889082 1.988321 -1.105912 2.787891

2. 按值排序

sort_values(by='column name')

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

示例代碼:

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

運行結果:

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

處理缺失數(shù)據(jù)

示例代碼:

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

運行結果:

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

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

示例代碼:

  1. # isnull
  2. print(df_data.isnull())

運行結果:

  1. 0 1 2
  2. 0 False False False
  3. 1 False False True
  4. 2 True False True
  5. 3 False False False

2. 丟棄缺失數(shù)據(jù):dropna()

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

  1. # dropna
  2. print(df_data.dropna())
  3. print(df_data.dropna(axis=1))

運行結果:

  1. 0 1 2
  2. 0 -0.281885 -0.786572 0.487126
  3. 3 1.000000 2.000000 3.000000
  4. 1
  5. 0 -0.786572
  6. 1 2.000000
  7. 2 4.000000
  8. 3 2.000000

3. 填充缺失數(shù)據(jù):fillna()

示例代碼:

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

運行結果:

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

層級索引(hierarchical indexing)

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

示例代碼:

  1. import pandas as pd
  2. import numpy as np
  3. ser_obj = pd.Series(np.random.randn(12),index=[
  4. ['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'd'],
  5. [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]
  6. ])
  7. print(ser_obj)

運行結果:

  1. a 0 0.099174
  2. 1 -0.310414
  3. 2 -0.558047
  4. b 0 1.742445
  5. 1 1.152924
  6. 2 -0.725332
  7. c 0 -0.150638
  8. 1 0.251660
  9. 2 0.063387
  10. d 0 1.080605
  11. 1 0.567547
  12. 2 -0.154148
  13. dtype: float64

MultiIndex索引對象

  • 打印這個Series的索引類型,顯示是MultiIndex

  • 直接將索引打印出來,可以看到有l(wèi)avels,和labels兩個信息。lavels表示兩個層級中分別有那些標簽,labels是每個位置分別是什么標簽。

示例代碼:

  1. print(type(ser_obj.index))
  2. print(ser_obj.index)

運行結果:

  1. <class 'pandas.indexes.multi.MultiIndex'>
  2. MultiIndex(levels=[['a', 'b', 'c', 'd'], [0, 1, 2]],
  3. 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]])

選取子集

  • 根據(jù)索引獲取數(shù)據(jù)。因為現(xiàn)在有兩層索引,當通過外層索引獲取數(shù)據(jù)的時候,可以直接利用外層索引的標簽來獲取。

  • 當要通過內層索引獲取數(shù)據(jù)的時候,在list中傳入兩個元素,前者是表示要選取的外層索引,后者表示要選取的內層索引。

1. 外層選?。?/p>

ser_obj['outer_label']

示例代碼:

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

運行結果:

  1. 0 -1.362096
  2. 1 1.558091
  3. 2 -0.452313
  4. dtype: float64

2. 內層選?。?/p>

ser_obj[:, 'inner_label']

示例代碼:

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

運行結果:

  1. a 0.826662
  2. b 0.015426
  3. c -0.452313
  4. d -0.051063
  5. dtype: float64

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

交換分層順序

1. swaplevel()

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

示例代碼:

print(ser_obj.swaplevel())

運行結果:

  1. 0 a 0.099174
  2. 1 a -0.310414
  3. 2 a -0.558047
  4. 0 b 1.742445
  5. 1 b 1.152924
  6. 2 b -0.725332
  7. 0 c -0.150638
  8. 1 c 0.251660
  9. 2 c 0.063387
  10. 0 d 1.080605
  11. 1 d 0.567547
  12. 2 d -0.154148
  13. dtype: float64

交換并排序分層

sortlevel()

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

示例代碼:

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

運行結果:

  1. 0 a 0.099174
  2. b 1.742445
  3. c -0.150638
  4. d 1.080605
  5. 1 a -0.310414
  6. b 1.152924
  7. c 0.251660
  8. d 0.567547
  9. 2 a -0.558047
  10. b -0.725332
  11. c 0.063387
  12. d -0.154148
  13. dtype: float64

Pandas統(tǒng)計計算和描述

示例代碼:

  1. import numpy as np
  2. import pandas as pd
  3. df_obj = pd.DataFrame(np.random.randn(5,4), columns = ['a', 'b', 'c', 'd'])
  4. print(df_obj)

運行結果:

  1. a b c d
  2. 0 1.469682 1.948965 1.373124 -0.564129
  3. 1 -1.466670 -0.494591 0.467787 -2.007771
  4. 2 1.368750 0.532142 0.487862 -1.130825
  5. 3 -0.758540 -0.479684 1.239135 1.073077
  6. 4 -0.007470 0.997034 2.669219 0.742070

常用的統(tǒng)計計算

sum, mean, max, min…

axis=0 按列統(tǒng)計,axis=1按行統(tǒng)計

skipna 排除缺失值, 默認為True

示例代碼:

  1. df_obj.sum()
  2. df_obj.max()
  3. df_obj.min(axis=1, skipna=False)

運行結果:

  1. a 0.605751
  2. b 2.503866
  3. c 6.237127
  4. d -1.887578
  5. dtype: float64
  6. a 1.469682
  7. b 1.948965
  8. c 2.669219
  9. d 1.073077
  10. dtype: float64
  11. 0 -0.564129
  12. 1 -2.007771
  13. 2 -1.130825
  14. 3 -0.758540
  15. 4 -0.007470
  16. dtype: float64

常用的統(tǒng)計描述

describe 產生多個統(tǒng)計數(shù)據(jù)

示例代碼:

print(df_obj.describe())

運行結果:

  1. a b c d
  2. count 5.000000 5.000000 5.000000 5.000000
  3. mean 0.180305 0.106488 0.244978 0.178046
  4. std 0.641945 0.454340 1.064356 1.144416
  5. min -0.677175 -0.490278 -1.164928 -1.574556
  6. 25% -0.064069 -0.182920 -0.464013 -0.089962
  7. 50% 0.231722 0.127846 0.355859 0.190482
  8. 75% 0.318854 0.463377 1.169750 0.983663
  9. max 1.092195 0.614413 1.328220 1.380601

常用的統(tǒng)計描述方法:

Pandas分組與聚合

分組 (groupby)

  • 對數(shù)據(jù)集進行分組,然后對每組進行統(tǒng)計分析

  • SQL能夠對數(shù)據(jù)進行過濾,分組聚合

  • pandas能利用groupby進行更加復雜的分組運算

  • 分組運算過程:split->apply->combine

    1. 拆分:進行分組的根據(jù)

    2. 應用:每個分組運行的計算規(guī)則

    3. 合并:把每個分組的計算結果合并起來

示例代碼:

  1. import pandas as pd
  2. import numpy as np
  3. dict_obj = {'key1' : ['a', 'b', 'a', 'b',
  4. 'a', 'b', 'a', 'a'],
  5. 'key2' : ['one', 'one', 'two', 'three',
  6. 'two', 'two', 'one', 'three'],
  7. 'data1': np.random.randn(8),
  8. 'data2': np.random.randn(8)}
  9. df_obj = pd.DataFrame(dict_obj)
  10. print(df_obj)

運行結果:

  1. data1 data2 key1 key2
  2. 0 0.974685 -0.672494 a one
  3. 1 -0.214324 0.758372 b one
  4. 2 1.508838 0.392787 a two
  5. 3 0.522911 0.630814 b three
  6. 4 1.347359 -0.177858 a two
  7. 5 -0.264616 1.017155 b two
  8. 6 -0.624708 0.450885 a one
  9. 7 -1.019229 -1.143825 a three

一、GroupBy對象:DataFrameGroupBy,SeriesGroupBy

1. 分組操作

groupby()進行分組,GroupBy對象沒有進行實際運算,只是包含分組的中間數(shù)據(jù)

按列名分組:obj.groupby(‘label’)

示例代碼:

  1. # dataframe根據(jù)key1進行分組
  2. print(type(df_obj.groupby('key1')))
  3. # dataframe的 data1 列根據(jù) key1 進行分組
  4. print(type(df_obj['data1'].groupby(df_obj['key1'])))

運行結果:

  1. <class 'pandas.core.groupby.DataFrameGroupBy'>
  2. <class 'pandas.core.groupby.SeriesGroupBy'>

2. 分組運算

對GroupBy對象進行分組運算/多重分組運算,如mean()

非數(shù)值數(shù)據(jù)不進行分組運算

示例代碼:

  1. # 分組運算
  2. grouped1 = df_obj.groupby('key1')
  3. print(grouped1.mean())
  4. grouped2 = df_obj['data1'].groupby(df_obj['key1'])
  5. print(grouped2.mean())

運行結果:

  1. data1 data2
  2. key1
  3. a 0.437389 -0.230101
  4. b 0.014657 0.802114
  5. key1
  6. a 0.437389
  7. b 0.014657
  8. Name: data1, dtype: float64

size() 返回每個分組的元素個數(shù)

示例代碼:

  1. # size
  2. print(grouped1.size())
  3. print(grouped2.size())

運行結果:

  1. key1
  2. a 5
  3. b 3
  4. dtype: int64
  5. key1
  6. a 5
  7. b 3
  8. dtype: int64

3. 按自定義的key分組

obj.groupby(self_def_key)

自定義的key可為列表或多層列表

obj.groupby([‘label1’, ‘label2’])->多層dataframe

示例代碼:

  1. # 按自定義key分組,列表
  2. self_def_key = [0, 1, 2, 3, 3, 4, 5, 7]
  3. print(df_obj.groupby(self_def_key).size())
  4. # 按自定義key分組,多層列表
  5. print(df_obj.groupby([df_obj['key1'], df_obj['key2']]).size())
  6. # 按多個列多層分組
  7. grouped2 = df_obj.groupby(['key1', 'key2'])
  8. print(grouped2.size())
  9. # 多層分組按key的順序進行
  10. grouped3 = df_obj.groupby(['key2', 'key1'])
  11. print(grouped3.mean())
  12. # unstack可以將多層索引的結果轉換成單層的dataframe
  13. print(grouped3.mean().unstack())

運行結果:

  1. 0 1
  2. 1 1
  3. 2 1
  4. 3 2
  5. 4 1
  6. 5 1
  7. 7 1
  8. dtype: int64
  9. key1 key2
  10. a one 2
  11. three 1
  12. two 2
  13. b one 1
  14. three 1
  15. two 1
  16. dtype: int64
  17. key1 key2
  18. a one 2
  19. three 1
  20. two 2
  21. b one 1
  22. three 1
  23. two 1
  24. dtype: int64
  25. data1 data2
  26. key2 key1
  27. one a 0.174988 -0.110804
  28. b -0.214324 0.758372
  29. three a -1.019229 -1.143825
  30. b 0.522911 0.630814
  31. two a 1.428099 0.107465
  32. b -0.264616 1.017155
  33. data1 data2
  34. key1 a b a b
  35. key2
  36. one 0.174988 -0.214324 -0.110804 0.758372
  37. three -1.019229 0.522911 -1.143825 0.630814
  38. two 1.428099 -0.264616 0.107465 1.017155

二、GroupBy對象支持迭代操作

每次迭代返回一個元組 (group_name, group_data)

可用于分組數(shù)據(jù)的具體運算

1. 單層分組

示例代碼:

  1. # 單層分組,根據(jù)key1
  2. for group_name, group_data in grouped1:
  3. print(group_name)
  4. print(group_data)

運行結果:

  1. a
  2. data1 data2 key1 key2
  3. 0 0.974685 -0.672494 a one
  4. 2 1.508838 0.392787 a two
  5. 4 1.347359 -0.177858 a two
  6. 6 -0.624708 0.450885 a one
  7. 7 -1.019229 -1.143825 a three
  8. b
  9. data1 data2 key1 key2
  10. 1 -0.214324 0.758372 b one
  11. 3 0.522911 0.630814 b three
  12. 5 -0.264616 1.017155 b two

2. 多層分組

示例代碼:

  1. # 多層分組,根據(jù)key1 和 key2
  2. for group_name, group_data in grouped2:
  3. print(group_name)
  4. print(group_data)

運行結果:

  1. ('a', 'one')
  2. data1 data2 key1 key2
  3. 0 0.974685 -0.672494 a one
  4. 6 -0.624708 0.450885 a one
  5. ('a', 'three')
  6. data1 data2 key1 key2
  7. 7 -1.019229 -1.143825 a three
  8. ('a', 'two')
  9. data1 data2 key1 key2
  10. 2 1.508838 0.392787 a two
  11. 4 1.347359 -0.177858 a two
  12. ('b', 'one')
  13. data1 data2 key1 key2
  14. 1 -0.214324 0.758372 b one
  15. ('b', 'three')
  16. data1 data2 key1 key2
  17. 3 0.522911 0.630814 b three
  18. ('b', 'two')
  19. data1 data2 key1 key2
  20. 5 -0.264616 1.017155 b two

三、GroupBy對象可以轉換成列表或字典

示例代碼:

  1. # GroupBy對象轉換list
  2. print(list(grouped1))
  3. # GroupBy對象轉換dict
  4. print(dict(list(grouped1)))

運行結果:

  1. [('a', data1 data2 key1 key2
  2. 0 0.974685 -0.672494 a one
  3. 2 1.508838 0.392787 a two
  4. 4 1.347359 -0.177858 a two
  5. 6 -0.624708 0.450885 a one
  6. 7 -1.019229 -1.143825 a three),
  7. ('b', data1 data2 key1 key2
  8. 1 -0.214324 0.758372 b one
  9. 3 0.522911 0.630814 b three
  10. 5 -0.264616 1.017155 b two)]
  11. {'a': data1 data2 key1 key2
  12. 0 0.974685 -0.672494 a one
  13. 2 1.508838 0.392787 a two
  14. 4 1.347359 -0.177858 a two
  15. 6 -0.624708 0.450885 a one
  16. 7 -1.019229 -1.143825 a three,
  17. 'b': data1 data2 key1 key2
  18. 1 -0.214324 0.758372 b one
  19. 3 0.522911 0.630814 b three
  20. 5 -0.264616 1.017155 b two}

1. 按列分組、按數(shù)據(jù)類型分組

示例代碼:

  1. # 按列分組
  2. print(df_obj.dtypes)
  3. # 按數(shù)據(jù)類型分組
  4. print(df_obj.groupby(df_obj.dtypes, axis=1).size())
  5. print(df_obj.groupby(df_obj.dtypes, axis=1).sum())

運行結果:

  1. data1 float64
  2. data2 float64
  3. key1 object
  4. key2 object
  5. dtype: object
  6. float64 2
  7. object 2
  8. dtype: int64
  9. float64 object
  10. 0 0.302191 a one
  11. 1 0.544048 b one
  12. 2 1.901626 a two
  13. 3 1.153725 b three
  14. 4 1.169501 a two
  15. 5 0.752539 b two
  16. 6 -0.173823 a one
  17. 7 -2.163054 a three

2. 其他分組方法

示例代碼:

  1. df_obj2 = pd.DataFrame(np.random.randint(1, 10, (5,5)),
  2. columns=['a', 'b', 'c', 'd', 'e'],
  3. index=['A', 'B', 'C', 'D', 'E'])
  4. df_obj2.ix[1, 1:4] = np.NaN
  5. print(df_obj2)

運行結果:

  1. a b c d e
  2. A 7 2.0 4.0 5.0 8
  3. B 4 NaN NaN NaN 1
  4. C 3 2.0 5.0 4.0 6
  5. D 3 1.0 9.0 7.0 3
  6. E 6 1.0 6.0 8.0 1

3. 通過字典分組

示例代碼:

  1. # 通過字典分組
  2. mapping_dict = {'a':'Python', 'b':'Python', 'c':'Java', 'd':'C', 'e':'Java'}
  3. print(df_obj2.groupby(mapping_dict, axis=1).size())
  4. print(df_obj2.groupby(mapping_dict, axis=1).count()) # 非NaN的個數(shù)
  5. print(df_obj2.groupby(mapping_dict, axis=1).sum())

運行結果:

  1. C 1
  2. Java 2
  3. Python 2
  4. dtype: int64
  5. C Java Python
  6. A 1 2 2
  7. B 0 1 1
  8. C 1 2 2
  9. D 1 2 2
  10. E 1 2 2
  11. C Java Python
  12. A 5.0 12.0 9.0
  13. B NaN 1.0 4.0
  14. C 4.0 11.0 5.0
  15. D 7.0 12.0 4.0
  16. E 8.0 7.0 7.0

4. 通過函數(shù)分組,函數(shù)傳入的參數(shù)為行索引或列索引

示例代碼:

  1. # 通過函數(shù)分組
  2. df_obj3 = pd.DataFrame(np.random.randint(1, 10, (5,5)),
  3. columns=['a', 'b', 'c', 'd', 'e'],
  4. index=['AA', 'BBB', 'CC', 'D', 'EE'])
  5. #df_obj3
  6. def group_key(idx):
  7. """
  8. idx 為列索引或行索引
  9. """
  10. #return idx
  11. return len(idx)
  12. print(df_obj3.groupby(group_key).size())
  13. # 以上自定義函數(shù)等價于
  14. #df_obj3.groupby(len).size()

運行結果:

  1. 1 1
  2. 2 3
  3. 3 1
  4. dtype: int64

5. 通過索引級別分組

示例代碼:

  1. # 通過索引級別分組
  2. columns = pd.MultiIndex.from_arrays([['Python', 'Java', 'Python', 'Java', 'Python'],
  3. ['A', 'A', 'B', 'C', 'B']], names=['language', 'index'])
  4. df_obj4 = pd.DataFrame(np.random.randint(1, 10, (5, 5)), columns=columns)
  5. print(df_obj4)
  6. # 根據(jù)language進行分組
  7. print(df_obj4.groupby(level='language', axis=1).sum())
  8. # 根據(jù)index進行分組
  9. print(df_obj4.groupby(level='index', axis=1).sum())

運行結果:

  1. language Python Java Python Java Python
  2. index A A B C B
  3. 0 2 7 8 4 3
  4. 1 5 2 6 1 2
  5. 2 6 4 4 5 2
  6. 3 4 7 4 3 1
  7. 4 7 4 3 4 8
  8. language Java Python
  9. 0 11 13
  10. 1 3 13
  11. 2 9 12
  12. 3 10 9
  13. 4 8 18
  14. index A B C
  15. 0 9 11 4
  16. 1 7 8 1
  17. 2 10 6 5
  18. 3 11 5 3
  19. 4 11 11 4

聚合 (aggregation)

  • 數(shù)組產生標量的過程,如mean()、count()等

  • 常用于對分組后的數(shù)據(jù)進行計算

示例代碼:

  1. dict_obj = {'key1' : ['a', 'b', 'a', 'b',
  2. 'a', 'b', 'a', 'a'],
  3. 'key2' : ['one', 'one', 'two', 'three',
  4. 'two', 'two', 'one', 'three'],
  5. 'data1': np.random.randint(1,10, 8),
  6. 'data2': np.random.randint(1,10, 8)}
  7. df_obj5 = pd.DataFrame(dict_obj)
  8. print(df_obj5)

運行結果:

  1. data1 data2 key1 key2
  2. 0 3 7 a one
  3. 1 1 5 b one
  4. 2 7 4 a two
  5. 3 2 4 b three
  6. 4 6 4 a two
  7. 5 9 9 b two
  8. 6 3 5 a one
  9. 7 8 4 a three

1. 內置的聚合函數(shù)

sum(), mean(), max(), min(), count(), size(), describe()

示例代碼:

  1. print(df_obj5.groupby('key1').sum())
  2. print(df_obj5.groupby('key1').max())
  3. print(df_obj5.groupby('key1').min())
  4. print(df_obj5.groupby('key1').mean())
  5. print(df_obj5.groupby('key1').size())
  6. print(df_obj5.groupby('key1').count())
  7. print(df_obj5.groupby('key1').describe())

運行結果:

  1. data1 data2
  2. key1
  3. a 27 24
  4. b 12 18
  5. data1 data2 key2
  6. key1
  7. a 8 7 two
  8. b 9 9 two
  9. data1 data2 key2
  10. key1
  11. a 3 4 one
  12. b 1 4 one
  13. data1 data2
  14. key1
  15. a 5.4 4.8
  16. b 4.0 6.0
  17. key1
  18. a 5
  19. b 3
  20. dtype: int64
  21. data1 data2 key2
  22. key1
  23. a 5 5 5
  24. b 3 3 3
  25. data1 data2
  26. key1
  27. a count 5.000000 5.000000
  28. mean 5.400000 4.800000
  29. std 2.302173 1.303840
  30. min 3.000000 4.000000
  31. 25% 3.000000 4.000000
  32. 50% 6.000000 4.000000
  33. 75% 7.000000 5.000000
  34. max 8.000000 7.000000
  35. b count 3.000000 3.000000
  36. mean 4.000000 6.000000
  37. std 4.358899 2.645751
  38. min 1.000000 4.000000
  39. 25% 1.500000 4.500000
  40. 50% 2.000000 5.000000
  41. 75% 5.500000 7.000000
  42. max 9.000000 9.000000

2. 可自定義函數(shù),傳入agg方法中

grouped.agg(func)

func的參數(shù)為groupby索引對應的記錄

示例代碼:

  1. # 自定義聚合函數(shù)
  2. def peak_range(df):
  3. """
  4. 返回數(shù)值范圍
  5. """
  6. #print type(df) #參數(shù)為索引所對應的記錄
  7. return df.max() - df.min()
  8. print(df_obj5.groupby('key1').agg(peak_range))
  9. print(df_obj.groupby('key1').agg(lambda df : df.max() - df.min()))

運行結果:

  1. data1 data2
  2. key1
  3. a 5 3
  4. b 8 5
  5. data1 data2
  6. key1
  7. a 2.528067 1.594711
  8. b 0.787527 0.386341
  9. In [25]:

3. 應用多個聚合函數(shù)

同時應用多個函數(shù)進行聚合操作,使用函數(shù)列表

示例代碼:

  1. # 應用多個聚合函數(shù)
  2. # 同時應用多個聚合函數(shù)
  3. print(df_obj.groupby('key1').agg(['mean', 'std', 'count', peak_range])) # 默認列名為函數(shù)名
  4. print(df_obj.groupby('key1').agg(['mean', 'std', 'count', ('range', peak_range)])) # 通過元組提供新的列名

運行結果:

  1. data1 data2
  2. mean std count peak_range mean std count peak_range
  3. key1
  4. a 0.437389 1.174151 5 2.528067 -0.230101 0.686488 5 1.594711
  5. b 0.014657 0.440878 3 0.787527 0.802114 0.196850 3 0.386341
  6. data1 data2
  7. mean std count range mean std count range
  8. key1
  9. a 0.437389 1.174151 5 2.528067 -0.230101 0.686488 5 1.594711
  10. b 0.014657 0.440878 3 0.787527 0.802114 0.196850 3 0.386341

4. 對不同的列分別作用不同的聚合函數(shù),使用dict

示例代碼:

  1. # 每列作用不同的聚合函數(shù)
  2. dict_mapping = {'data1':'mean',
  3. 'data2':'sum'}
  4. print(df_obj.groupby('key1').agg(dict_mapping))
  5. dict_mapping = {'data1':['mean','max'],
  6. 'data2':'sum'}
  7. print(df_obj.groupby('key1').agg(dict_mapping))

運行結果:

  1. data1 data2
  2. key1
  3. a 0.437389 -1.150505
  4. b 0.014657 2.406341
  5. data1 data2
  6. mean max sum
  7. key1
  8. a 0.437389 1.508838 -1.150505
  9. b 0.014657 0.522911 2.406341

5. 常用的內置聚合函數(shù)

數(shù)據(jù)的分組運算

示例代碼:

  1. import pandas as pd
  2. import numpy as np
  3. dict_obj = {'key1' : ['a', 'b', 'a', 'b',
  4. 'a', 'b', 'a', 'a'],
  5. 'key2' : ['one', 'one', 'two', 'three',
  6. 'two', 'two', 'one', 'three'],
  7. 'data1': np.random.randint(1, 10, 8),
  8. 'data2': np.random.randint(1, 10, 8)}
  9. df_obj = pd.DataFrame(dict_obj)
  10. print(df_obj)
  11. # 按key1分組后,計算data1,data2的統(tǒng)計信息并附加到原始表格中,并添加表頭前綴
  12. k1_sum = df_obj.groupby('key1').sum().add_prefix('sum_')
  13. print(k1_sum)

運行結果:

  1. data1 data2 key1 key2
  2. 0 5 1 a one
  3. 1 7 8 b one
  4. 2 1 9 a two
  5. 3 2 6 b three
  6. 4 9 8 a two
  7. 5 8 3 b two
  8. 6 3 5 a one
  9. 7 8 3 a three
  10. sum_data1 sum_data2
  11. key1
  12. a 26 26
  13. b 17 17

聚合運算后會改變原始數(shù)據(jù)的形狀,

如何保持原始數(shù)據(jù)的形狀?

1. merge

使用merge的外連接,比較復雜

示例代碼:

  1. # 方法1,使用merge
  2. k1_sum_merge = pd.merge(df_obj, k1_sum, left_on='key1', right_index=True)
  3. print(k1_sum_merge)

運行結果:

  1. data1 data2 key1 key2 sum_data1 sum_data2
  2. 0 5 1 a one 26 26
  3. 2 1 9 a two 26 26
  4. 4 9 8 a two 26 26
  5. 6 3 5 a one 26 26
  6. 7 8 3 a three 26 26
  7. 1 7 8 b one 17 17
  8. 3 2 6 b three 17 17
  9. 5 8 3 b two 17 17

2. transform

transform的計算結果和原始數(shù)據(jù)的形狀保持一致,

如:grouped.transform(np.sum)

示例代碼:

  1. # 方法2,使用transform
  2. k1_sum_tf = df_obj.groupby('key1').transform(np.sum).add_prefix('sum_')
  3. df_obj[k1_sum_tf.columns] = k1_sum_tf
  4. print(df_obj)

運行結果:

  1. data1 data2 key1 key2 sum_data1 sum_data2 sum_key2
  2. 0 5 1 a one 26 26 onetwotwoonethree
  3. 1 7 8 b one 17 17 onethreetwo
  4. 2 1 9 a two 26 26 onetwotwoonethree
  5. 3 2 6 b three 17 17 onethreetwo
  6. 4 9 8 a two 26 26 onetwotwoonethree
  7. 5 8 3 b two 17 17 onethreetwo
  8. 6 3 5 a one 26 26 onetwotwoonethree
  9. 7 8 3 a three 26 26 onetwotwoonethree

也可傳入自定義函數(shù),

示例代碼:

  1. # 自定義函數(shù)傳入transform
  2. def diff_mean(s):
  3. """
  4. 返回數(shù)據(jù)與均值的差值
  5. """
  6. return s - s.mean()
  7. print(df_obj.groupby('key1').transform(diff_mean))

運行結果:

  1. data1 data2 sum_data1 sum_data2
  2. 0 -0.200000 -4.200000 0 0
  3. 1 1.333333 2.333333 0 0
  4. 2 -4.200000 3.800000 0 0
  5. 3 -3.666667 0.333333 0 0
  6. 4 3.800000 2.800000 0 0
  7. 5 2.333333 -2.666667 0 0
  8. 6 -2.200000 -0.200000 0 0
  9. 7 2.800000 -2.200000 0 0

groupby.apply(func)

func函數(shù)也可以在各分組上分別調用,最后結果通過pd.concat組裝到一起(數(shù)據(jù)合并)

示例代碼:

  1. import pandas as pd
  2. import numpy as np
  3. dataset_path = './starcraft.csv'
  4. df_data = pd.read_csv(dataset_path, usecols=['LeagueIndex', 'Age', 'HoursPerWeek',
  5. 'TotalHours', 'APM'])
  6. def top_n(df, n=3, column='APM'):
  7. """
  8. 返回每個分組按 column 的 top n 數(shù)據(jù)
  9. """
  10. return df.sort_values(by=column, ascending=False)[:n]
  11. print(df_data.groupby('LeagueIndex').apply(top_n))

運行結果:

  1. LeagueIndex Age HoursPerWeek TotalHours APM
  2. LeagueIndex
  3. 1 2214 1 20.0 12.0 730.0 172.9530
  4. 2246 1 27.0 8.0 250.0 141.6282
  5. 1753 1 20.0 28.0 100.0 139.6362
  6. 2 3062 2 20.0 6.0 100.0 179.6250
  7. 3229 2 16.0 24.0 110.0 156.7380
  8. 1520 2 29.0 6.0 250.0 151.6470
  9. 3 1557 3 22.0 6.0 200.0 226.6554
  10. 484 3 19.0 42.0 450.0 220.0692
  11. 2883 3 16.0 8.0 800.0 208.9500
  12. 4 2688 4 26.0 24.0 990.0 249.0210
  13. 1759 4 16.0 6.0 75.0 229.9122
  14. 2637 4 23.0 24.0 650.0 227.2272
  15. 5 3277 5 18.0 16.0 950.0 372.6426
  16. 93 5 17.0 36.0 720.0 335.4990
  17. 202 5 37.0 14.0 800.0 327.7218
  18. 6 734 6 16.0 28.0 730.0 389.8314
  19. 2746 6 16.0 28.0 4000.0 350.4114
  20. 1810 6 21.0 14.0 730.0 323.2506
  21. 7 3127 7 23.0 42.0 2000.0 298.7952
  22. 104 7 21.0 24.0 1000.0 286.4538
  23. 1654 7 18.0 98.0 700.0 236.0316
  24. 8 3393 8 NaN NaN NaN 375.8664
  25. 3373 8 NaN NaN NaN 364.8504
  26. 3372 8 NaN NaN NaN 355.3518

1. 產生層級索引:外層索引是分組名,內層索引是df_obj的行索引

示例代碼:

  1. # apply函數(shù)接收的參數(shù)會傳入自定義的函數(shù)中
  2. print(df_data.groupby('LeagueIndex').apply(top_n, n=2, column='Age'))

運行結果:

  1. LeagueIndex Age HoursPerWeek TotalHours APM
  2. LeagueIndex
  3. 1 3146 1 40.0 12.0 150.0 38.5590
  4. 3040 1 39.0 10.0 500.0 29.8764
  5. 2 920 2 43.0 10.0 730.0 86.0586
  6. 2437 2 41.0 4.0 200.0 54.2166
  7. 3 1258 3 41.0 14.0 800.0 77.6472
  8. 2972 3 40.0 10.0 500.0 60.5970
  9. 4 1696 4 44.0 6.0 500.0 89.5266
  10. 1729 4 39.0 8.0 500.0 86.7246
  11. 5 202 5 37.0 14.0 800.0 327.7218
  12. 2745 5 37.0 18.0 1000.0 123.4098
  13. 6 3069 6 31.0 8.0 800.0 133.1790
  14. 2706 6 31.0 8.0 700.0 66.9918
  15. 7 2813 7 26.0 36.0 1300.0 188.5512
  16. 1992 7 26.0 24.0 1000.0 219.6690
  17. 8 3340 8 NaN NaN NaN 189.7404
  18. 3341 8 NaN NaN NaN 287.8128

2. 禁止層級索引, group_keys=False

示例代碼:

print(df_data.groupby('LeagueIndex', group_keys=False).apply(top_n))

運行結果:

  1. LeagueIndex Age HoursPerWeek TotalHours APM
  2. 2214 1 20.0 12.0 730.0 172.9530
  3. 2246 1 27.0 8.0 250.0 141.6282
  4. 1753 1 20.0 28.0 100.0 139.6362
  5. 3062 2 20.0 6.0 100.0 179.6250
  6. 3229 2 16.0 24.0 110.0 156.7380
  7. 1520 2 29.0 6.0 250.0 151.6470
  8. 1557 3 22.0 6.0 200.0 226.6554
  9. 484 3 19.0 42.0 450.0 220.0692
  10. 2883 3 16.0 8.0 800.0 208.9500
  11. 2688 4 26.0 24.0 990.0 249.0210
  12. 1759 4 16.0 6.0 75.0 229.9122
  13. 2637 4 23.0 24.0 650.0 227.2272
  14. 3277 5 18.0 16.0 950.0 372.6426
  15. 93 5 17.0 36.0 720.0 335.4990
  16. 202 5 37.0 14.0 800.0 327.7218
  17. 734 6 16.0 28.0 730.0 389.8314
  18. 2746 6 16.0 28.0 4000.0 350.4114
  19. 1810 6 21.0 14.0 730.0 323.2506
  20. 3127 7 23.0 42.0 2000.0 298.7952
  21. 104 7 21.0 24.0 1000.0 286.4538
  22. 1654 7 18.0 98.0 700.0 236.0316
  23. 3393 8 NaN NaN NaN 375.8664
  24. 3373 8 NaN NaN NaN 364.8504
  25. 3372 8 NaN NaN NaN 355.3518

apply可以用來處理不同分組內的缺失數(shù)據(jù)填充,填充該分組的均值。

數(shù)據(jù)清洗

  • 數(shù)據(jù)清洗是數(shù)據(jù)分析關鍵的一步,直接影響之后的處理工作

  • 數(shù)據(jù)需要修改嗎?有什么需要修改的嗎?數(shù)據(jù)應該怎么調整才能適用于接下來的分析和挖掘?

  • 是一個迭代的過程,實際項目中可能需要不止一次地執(zhí)行這些清洗操作

  • 處理缺失數(shù)據(jù):pd.fillna(),pd.dropna()

數(shù)據(jù)連接(pd.merge)

  • pd.merge

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

  • 類似數(shù)據(jù)庫的連接操作

示例代碼:

  1. import pandas as pd
  2. import numpy as np
  3. df_obj1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
  4. 'data1' : np.random.randint(0,10,7)})
  5. df_obj2 = pd.DataFrame({'key': ['a', 'b', 'd'],
  6. 'data2' : np.random.randint(0,10,3)})
  7. print(df_obj1)
  8. print(df_obj2)

運行結果:

  1. data1 key
  2. data1 key
  3. 0 8 b
  4. 1 8 b
  5. 2 3 a
  6. 3 5 c
  7. 4 4 a
  8. 5 9 a
  9. 6 6 b
  10. data2 key
  11. 0 9 a
  12. 1 0 b
  13. 2 3 d

1. 默認將重疊列的列名作為“外鍵”進行連接

示例代碼:

  1. # 默認將重疊列的列名作為“外鍵”進行連接
  2. print(pd.merge(df_obj1, df_obj2))

運行結果:

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

2. on顯示指定“外鍵”

示例代碼:

  1. # on顯示指定“外鍵”
  2. print(pd.merge(df_obj1, df_obj2, on='key'))

運行結果:

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

3. left_on,左側數(shù)據(jù)的“外鍵”,right_on,右側數(shù)據(jù)的“外鍵”

示例代碼:

  1. # left_on,right_on分別指定左側數(shù)據(jù)和右側數(shù)據(jù)的“外鍵”
  2. # 更改列名
  3. df_obj1 = df_obj1.rename(columns={'key':'key1'})
  4. df_obj2 = df_obj2.rename(columns={'key':'key2'})
  5. print(pd.merge(df_obj1, df_obj2, left_on='key1', right_on='key2'))

運行結果:

  1. data1 key1 data2 key2
  2. 0 8 b 0 b
  3. 1 8 b 0 b
  4. 2 6 b 0 b
  5. 3 3 a 9 a
  6. 4 4 a 9 a
  7. 5 9 a 9 a

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

how指定連接方式

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

示例代碼:

  1. # “外連接”
  2. print(pd.merge(df_obj1, df_obj2, left_on='key1', right_on='key2', how='outer'))

運行結果:

  1. data1 key1 data2 key2
  2. 0 8.0 b 0.0 b
  3. 1 8.0 b 0.0 b
  4. 2 6.0 b 0.0 b
  5. 3 3.0 a 9.0 a
  6. 4 4.0 a 9.0 a
  7. 5 9.0 a 9.0 a
  8. 6 5.0 c NaN NaN
  9. 7 NaN NaN 3.0 d

5. “左連接”(left)

示例代碼:

  1. # 左連接
  2. print(pd.merge(df_obj1, df_obj2, left_on='key1', right_on='key2', how='left'))

運行結果:

  1. data1 key1 data2 key2
  2. 0 8 b 0.0 b
  3. 1 8 b 0.0 b
  4. 2 3 a 9.0 a
  5. 3 5 c NaN NaN
  6. 4 4 a 9.0 a
  7. 5 9 a 9.0 a
  8. 6 6 b 0.0 b

6. “右連接”(right)

示例代碼:

  1. # 右連接
  2. print(pd.merge(df_obj1, df_obj2, left_on='key1', right_on='key2', how='right'))

運行結果:

  1. data1 key1 data2 key2
  2. 0 8.0 b 0 b
  3. 1 8.0 b 0 b
  4. 2 6.0 b 0 b
  5. 3 3.0 a 9 a
  6. 4 4.0 a 9 a
  7. 5 9.0 a 9 a
  8. 6 NaN NaN 3 d

7. 處理重復列名

suffixes,默認為_x, _y

示例代碼:

  1. # 處理重復列名
  2. df_obj1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
  3. 'data' : np.random.randint(0,10,7)})
  4. df_obj2 = pd.DataFrame({'key': ['a', 'b', 'd'],
  5. 'data' : np.random.randint(0,10,3)})
  6. print(pd.merge(df_obj1, df_obj2, on='key', suffixes=('_left', '_right')))

運行結果:

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

8. 按索引連接

left_index=True或right_index=True

示例代碼:

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

運行結果:

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

數(shù)據(jù)合并(pd.concat)

  • 沿軸方向將多個對象合并到一起

1. NumPy的concat

np.concatenate

示例代碼:

  1. import numpy as np
  2. import pandas as pd
  3. arr1 = np.random.randint(0, 10, (3, 4))
  4. arr2 = np.random.randint(0, 10, (3, 4))
  5. print(arr1)
  6. print(arr2)
  7. print(np.concatenate([arr1, arr2]))
  8. print(np.concatenate([arr1, arr2], axis=1))

運行結果:

  1. # print(arr1)
  2. [[3 3 0 8]
  3. [2 0 3 1]
  4. [4 8 8 2]]
  5. # print(arr2)
  6. [[6 8 7 3]
  7. [1 6 8 7]
  8. [1 4 7 1]]
  9. # print(np.concatenate([arr1, arr2]))
  10. [[3 3 0 8]
  11. [2 0 3 1]
  12. [4 8 8 2]
  13. [6 8 7 3]
  14. [1 6 8 7]
  15. [1 4 7 1]]
  16. # print(np.concatenate([arr1, arr2], axis=1))
  17. [[3 3 0 8 6 8 7 3]
  18. [2 0 3 1 1 6 8 7]
  19. [4 8 8 2 1 4 7 1]]

2. pd.concat

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

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

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

1) index 沒有重復的情況

示例代碼:

  1. # index 沒有重復的情況
  2. ser_obj1 = pd.Series(np.random.randint(0, 10, 5), index=range(0,5))
  3. ser_obj2 = pd.Series(np.random.randint(0, 10, 4), index=range(5,9))
  4. ser_obj3 = pd.Series(np.random.randint(0, 10, 3), index=range(9,12))
  5. print(ser_obj1)
  6. print(ser_obj2)
  7. print(ser_obj3)
  8. print(pd.concat([ser_obj1, ser_obj2, ser_obj3]))
  9. print(pd.concat([ser_obj1, ser_obj2, ser_obj3], axis=1))

運行結果:

  1. # print(ser_obj1)
  2. 0 1
  3. 1 8
  4. 2 4
  5. 3 9
  6. 4 4
  7. dtype: int64
  8. # print(ser_obj2)
  9. 5 2
  10. 6 6
  11. 7 4
  12. 8 2
  13. dtype: int64
  14. # print(ser_obj3)
  15. 9 6
  16. 10 2
  17. 11 7
  18. dtype: int64
  19. # print(pd.concat([ser_obj1, ser_obj2, ser_obj3]))
  20. 0 1
  21. 1 8
  22. 2 4
  23. 3 9
  24. 4 4
  25. 5 2
  26. 6 6
  27. 7 4
  28. 8 2
  29. 9 6
  30. 10 2
  31. 11 7
  32. dtype: int64
  33. # print(pd.concat([ser_obj1, ser_obj2, ser_obj3], axis=1))
  34. 0 1 2
  35. 0 1.0 NaN NaN
  36. 1 5.0 NaN NaN
  37. 2 3.0 NaN NaN
  38. 3 2.0 NaN NaN
  39. 4 4.0 NaN NaN
  40. 5 NaN 9.0 NaN
  41. 6 NaN 8.0 NaN
  42. 7 NaN 3.0 NaN
  43. 8 NaN 6.0 NaN
  44. 9 NaN NaN 2.0
  45. 10 NaN NaN 3.0
  46. 11 NaN NaN 3.0

2) index 有重復的情況

示例代碼:

  1. # index 有重復的情況
  2. ser_obj1 = pd.Series(np.random.randint(0, 10, 5), index=range(5))
  3. ser_obj2 = pd.Series(np.random.randint(0, 10, 4), index=range(4))
  4. ser_obj3 = pd.Series(np.random.randint(0, 10, 3), index=range(3))
  5. print(ser_obj1)
  6. print(ser_obj2)
  7. print(ser_obj3)
  8. print(pd.concat([ser_obj1, ser_obj2, ser_obj3]))

運行結果:

  1. # print(ser_obj1)
  2. 0 0
  3. 1 3
  4. 2 7
  5. 3 2
  6. 4 5
  7. dtype: int64
  8. # print(ser_obj2)
  9. 0 5
  10. 1 1
  11. 2 9
  12. 3 9
  13. dtype: int64
  14. # print(ser_obj3)
  15. 0 8
  16. 1 7
  17. 2 9
  18. dtype: int64
  19. # print(pd.concat([ser_obj1, ser_obj2, ser_obj3]))
  20. 0 0
  21. 1 3
  22. 2 7
  23. 3 2
  24. 4 5
  25. 0 5
  26. 1 1
  27. 2 9
  28. 3 9
  29. 0 8
  30. 1 7
  31. 2 9
  32. dtype: int64
  33. # print(pd.concat([ser_obj1, ser_obj2, ser_obj3], axis=1, join='inner'))
  34. # join='inner' 將去除NaN所在的行或列
  35. 0 1 2
  36. 0 0 5 8
  37. 1 3 1 7
  38. 2 7 9 9

3) DataFrame合并時同時查看行索引和列索引有無重復

示例代碼:

  1. df_obj1 = pd.DataFrame(np.random.randint(0, 10, (3, 2)), index=['a', 'b', 'c'],
  2. columns=['A', 'B'])
  3. df_obj2 = pd.DataFrame(np.random.randint(0, 10, (2, 2)), index=['a', 'b'],
  4. columns=['C', 'D'])
  5. print(df_obj1)
  6. print(df_obj2)
  7. print(pd.concat([df_obj1, df_obj2]))
  8. print(pd.concat([df_obj1, df_obj2], axis=1, join='inner'))

運行結果:

  1. # print(df_obj1)
  2. A B
  3. a 3 3
  4. b 5 4
  5. c 8 6
  6. # print(df_obj2)
  7. C D
  8. a 1 9
  9. b 6 8
  10. # print(pd.concat([df_obj1, df_obj2]))
  11. A B C D
  12. a 3.0 3.0 NaN NaN
  13. b 5.0 4.0 NaN NaN
  14. c 8.0 6.0 NaN NaN
  15. a NaN NaN 1.0 9.0
  16. b NaN NaN 6.0 8.0
  17. # print(pd.concat([df_obj1, df_obj2], axis=1, join='inner'))
  18. A B C D
  19. a 3 3 1 9
  20. b 5 4 6 8

數(shù)據(jù)重構

1. stack

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

  • DataFrame->Series

示例代碼:

  1. import numpy as np
  2. import pandas as pd
  3. df_obj = pd.DataFrame(np.random.randint(0,10, (5,2)), columns=['data1', 'data2'])
  4. print(df_obj)
  5. stacked = df_obj.stack()
  6. print(stacked)

運行結果:

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

2. unstack

  • 將層級索引展開

  • Series->DataFrame

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

示例代碼:

  1. # 默認操作內層索引
  2. print(stacked.unstack())
  3. # 通過level指定操作索引的級別
  4. print(stacked.unstack(level=0))

運行結果:

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

數(shù)據(jù)轉換

一、 處理重復數(shù)據(jù)

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

示例代碼:

  1. import numpy as np
  2. import pandas as pd
  3. df_obj = pd.DataFrame({'data1' : ['a'] * 4 + ['b'] * 4,
  4. 'data2' : np.random.randint(0, 4, 8)})
  5. print(df_obj)
  6. print(df_obj.duplicated())

運行結果:

  1. # print(df_obj)
  2. data1 data2
  3. 0 a 3
  4. 1 a 2
  5. 2 a 3
  6. 3 a 3
  7. 4 b 1
  8. 5 b 0
  9. 6 b 3
  10. 7 b 0
  11. # print(df_obj.duplicated())
  12. 0 False
  13. 1 False
  14. 2 True
  15. 3 True
  16. 4 False
  17. 5 False
  18. 6 False
  19. 7 True
  20. dtype: bool

drop_duplicates() 過濾重復行

默認判斷全部列

可指定按某些列判斷

示例代碼:

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

運行結果:

  1. # print(df_obj.drop_duplicates())
  2. data1 data2
  3. 0 a 3
  4. 1 a 2
  5. 4 b 1
  6. 5 b 0
  7. 6 b 3
  8. # print(df_obj.drop_duplicates('data2'))
  9. data1 data2
  10. 0 a 3
  11. 1 a 2
  12. 4 b 1
  13. 5 b 0

3. 根據(jù)map傳入的函數(shù)對每行或每列進行轉換

  • Series根據(jù)map傳入的函數(shù)對每行或每列進行轉換

示例代碼:

  1. ser_obj = pd.Series(np.random.randint(0,10,10))
  2. print(ser_obj)
  3. print(ser_obj.map(lambda x : x ** 2))

運行結果:

  1. # print(ser_obj)
  2. 0 1
  3. 1 4
  4. 2 8
  5. 3 6
  6. 4 8
  7. 5 6
  8. 6 6
  9. 7 4
  10. 8 7
  11. 9 3
  12. dtype: int64
  13. # print(ser_obj.map(lambda x : x ** 2))
  14. 0 1
  15. 1 16
  16. 2 64
  17. 3 36
  18. 4 64
  19. 5 36
  20. 6 36
  21. 7 16
  22. 8 49
  23. 9 9
  24. dtype: int64

二、數(shù)據(jù)替換

replace根據(jù)值的內容進行替換

示例代碼:

  1. # 單個值替換單個值
  2. print(ser_obj.replace(1, -100))
  3. # 多個值替換一個值
  4. print(ser_obj.replace([6, 8], -100))
  5. # 多個值替換多個值
  6. print(ser_obj.replace([4, 7], [-100, -200]))

運行結果:

  1. # print(ser_obj.replace(1, -100))
  2. 0 -100
  3. 1 4
  4. 2 8
  5. 3 6
  6. 4 8
  7. 5 6
  8. 6 6
  9. 7 4
  10. 8 7
  11. 9 3
  12. dtype: int64
  13. # print(ser_obj.replace([6, 8], -100))
  14. 0 1
  15. 1 4
  16. 2 -100
  17. 3 -100
  18. 4 -100
  19. 5 -100
  20. 6 -100
  21. 7 4
  22. 8 7
  23. 9 3
  24. dtype: int64
  25. # print(ser_obj.replace([4, 7], [-100, -200]))
  26. 0 1
  27. 1 -100
  28. 2 8
  29. 3 6
  30. 4 8
  31. 5 6
  32. 6 6
  33. 7 -100
  34. 8 -200
  35. 9 3
  36. dtype: int64

聚類模型:K-Means

  • 聚類(clustering)屬于無監(jiān)督學習(unsupervised learning)

  • 無類別標記

  • 在線 demo:http:///kmeans.js

K-Means算法

  • 數(shù)據(jù)挖掘十大經典算法之一

  • 算法接收參數(shù)k;然后將樣本點劃分為k個聚類;同一聚類中的樣本相似度較高;不同聚類中的樣本相似度較小

算法思想:

以空間中k個樣本點為中心進行聚類,對最靠近它們的樣本點歸類。通過迭 代的方法,逐步更新各聚類中心,直至達到最好的聚類效果

算法描述:

  1. 選擇k個聚類的初始中心
  2. 在第n次迭代中,對任意一個樣本點,求其到k個聚類中心的距離,將該 樣本點歸類到距離最小的中心所在的聚類
  3. 利用均值等方法更新各類的中心值
  4. 對所有的k個聚類中心,如果利用2,3步的迭代更新后,達到穩(wěn)定,則迭代 結束。

優(yōu)缺點:

  • 優(yōu)點:速度快,簡單

  • 缺點:最終結果和初始點的選擇相關,容易陷入局部最優(yōu),需要給定k值

全球食品數(shù)據(jù)分析

項目參考:https://www./bhouwens/d/openfoodfacts/world-food-facts/how-much-sugar-do-we-eat/discussion

  1. # -*- coding : utf-8 -*-
  2. # 處理zip壓縮文件
  3. import zipfile
  4. import os
  5. import pandas as pd
  6. import matplotlib.pyplot as plt
  7. def unzip(zip_filepath, dest_path):
  8. """
  9. 解壓zip文件
  10. """
  11. with zipfile.ZipFile(zip_filepath) as zf:
  12. zf.extractall(path=dest_path)
  13. def get_dataset_filename(zip_filepath):
  14. """
  15. 獲取數(shù)據(jù)集文件名
  16. """
  17. with zipfile.ZipFile(zip_filepath) as zf:
  18. return zf.namelist()[0]
  19. def run_main():
  20. """
  21. 主函數(shù)
  22. """
  23. # 聲明變量
  24. dataset_path = './data' # 數(shù)據(jù)集路徑
  25. zip_filename = 'open-food-facts.zip' # zip文件名
  26. zip_filepath = os.path.join(dataset_path, zip_filename) # zip文件路徑
  27. dataset_filename = get_dataset_filename(zip_filepath) # 數(shù)據(jù)集文件名(在zip中)
  28. dataset_filepath = os.path.join(dataset_path, dataset_filename) # 數(shù)據(jù)集文件路徑
  29. print('解壓zip...', end='')
  30. unzip(zip_filepath, dataset_path)
  31. print('完成.')
  32. # 讀取數(shù)據(jù)
  33. data = pd.read_csv(dataset_filepath, usecols=['countries_en', 'additives_n'])
  34. # 分析各國家食物中的食品添加劑種類個數(shù)
  35. # 1. 數(shù)據(jù)清理
  36. # 去除缺失數(shù)據(jù)
  37. data = data.dropna() # 或者data.dropna(inplace=True)
  38. # 將國家名稱轉換為小寫
  39. # 課后練習:經過觀察發(fā)現(xiàn)'countries_en'中的數(shù)值不是單獨的國家名稱,
  40. # 有的是多個國家名稱用逗號隔開,如 Albania,Belgium,France,Germany,Italy,Netherlands,Spain
  41. # 正確的統(tǒng)計應該是將這些值拆開成多個行記錄,然后進行分組統(tǒng)計
  42. data['countries_en'] = data['countries_en'].str.lower()
  43. # 2. 數(shù)據(jù)分組統(tǒng)計
  44. country_additives = data['additives_n'].groupby(data['countries_en']).mean()
  45. # 3. 按值從大到小排序
  46. result = country_additives.sort_values(ascending=False)
  47. # 4. pandas可視化top10
  48. result.iloc[:10].plot.bar()
  49. plt.show()
  50. # 5. 保存處理結果
  51. result.to_csv('./country_additives.csv')
  52. # 刪除解壓數(shù)據(jù),清理空間
  53. if os.path.exists(dataset_filepath):
  54. os.remove(dataset_filepath)
  55. if __name__ == '__main__':
  56. run_main()

 

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多