目錄
什么是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配合能夠生成start和end范圍內以頻率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))
示例代碼:
ser_obj = pd.Series(range(10, 20))
運行結果:
<class 'pandas.core.series.Series'>
2. 獲取數(shù)據(jù)和索引
ser_obj.index 和 ser_obj.values
示例代碼:
運行結果:
[10 11 12 13 14 15 16 17 18 19] RangeIndex(start=0, stop=10, step=1)
3. 通過索引獲取數(shù)據(jù)
ser_obj[idx]
示例代碼:
運行結果:
4. 索引與數(shù)據(jù)的對應關系不被運算結果影響
示例代碼:
# 索引與數(shù)據(jù)的對應關系不被運算結果影響
運行結果:
5. 通過dict構建Series
示例代碼:
year_data = {2001: 17.8, 2002: 20.1, 2003: 16.5} ser_obj2 = pd.Series(year_data)
運行結果:
Int64Index([2001, 2002, 2003], dtype='int64')
name屬性
對象名:ser_obj.name
對象索引名:ser_obj.index.name
示例代碼:
ser_obj2.index.name = 'year'
運行結果:
Name: temp, dtype: float64
DataFrame
DataFrame是一個表格型的數(shù)據(jù)結構,它含有一組有序的列,每列可以是不同類型的值。DataFrame既有行索引也有列索引,它可以被看做是由Series組成的字典(共用同一個索引),數(shù)據(jù)是以二維結構存放的。
- 類似多維數(shù)組/表格數(shù)據(jù) (如,excel, R中的data.frame)
- 每列數(shù)據(jù)可以是不同的類型
- 索引包括列索引和行索引
1. 通過ndarray構建DataFrame
示例代碼:
array = np.random.randn(5,4) df_obj = pd.DataFrame(array)
運行結果:
[[ 0.83500594 -1.49290138 -0.53120106 -0.11313932] [ 0.64629762 -0.36779941 0.08011084 0.60080495] [-1.23458522 0.33409674 -0.58778195 -0.73610573] [-1.47651414 0.99400187 0.21001995 -0.90515656] [ 0.56669419 1.38238348 -0.49099007 1.94484598]] 0 0.835006 -1.492901 -0.531201 -0.113139 1 0.646298 -0.367799 0.080111 0.600805 2 -1.234585 0.334097 -0.587782 -0.736106 3 -1.476514 0.994002 0.210020 -0.905157 4 0.566694 1.382383 -0.490990 1.944846
2. 通過dict構建DataFrame
示例代碼:
'B': pd.Timestamp('20170426'), 'C': pd.Series(1, index=list(range(4)),dtype='float32'), 'D': np.array([3] * 4,dtype='int32'), 'E': ["Python","Java","C++","C"], df_obj2 = pd.DataFrame(dict_data)
運行結果:
0 1 2017-04-26 1.0 3 Python ITCast 1 1 2017-04-26 1.0 3 Java ITCast 2 1 2017-04-26 1.0 3 C++ ITCast 3 1 2017-04-26 1.0 3 C ITCast
3. 通過列索引獲取列數(shù)據(jù)(Series類型)
df_obj[col_idx] 或 df_obj.col_idx
示例代碼:
print(type(df_obj2['A']))
運行結果:
<class 'pandas.core.series.Series'>
4. 增加列數(shù)據(jù)
df_obj[new_col_idx] = data
類似Python的 dict添加key-value
示例代碼:
df_obj2['G'] = df_obj2['D'] + 4
運行結果:
0 1.0 2017-01-02 1.0 3 Python ITCast 7 1 1.0 2017-01-02 1.0 3 Java ITCast 7 2 1.0 2017-01-02 1.0 3 C++ ITCast 7 3 1.0 2017-01-02 1.0 3 C ITCast 7
5. 刪除列
del df_obj[col_idx]
示例代碼:
運行結果:
0 1.0 2017-01-02 1.0 3 Python ITCast 1 1.0 2017-01-02 1.0 3 Java ITCast 2 1.0 2017-01-02 1.0 3 C++ ITCast 3 1.0 2017-01-02 1.0 3 C ITCast
Pandas的索引操作
索引對象Index
1. Series和DataFrame中的索引都是Index對象
示例代碼:
print(type(ser_obj.index)) print(type(df_obj2.index))
運行結果:
<class 'pandas.indexes.range.RangeIndex'> <class 'pandas.indexes.numeric.Int64Index'> Int64Index([0, 1, 2, 3], dtype='int64')
2. 索引對象不可變,保證了數(shù)據(jù)的安全
示例代碼:
運行結果:
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-23-7f40a356d7d1> in <module>() ----> 2 df_obj2.index[0] = 2 /Users/Power/anaconda/lib/python3.6/site-packages/pandas/indexes/base.py in __setitem__(self, key, value) 1403 def __setitem__(self, key, value): -> 1404 raise TypeError("Index does not support mutable operations") 1406 def __getitem__(self, key): TypeError: Index does not support mutable operations
常見的Index種類
- Index,索引
- Int64Index,整數(shù)索引
- MultiIndex,層級索引
- DatetimeIndex,時間戳類型
Series索引
1. index 指定行索引名
示例代碼:
ser_obj = pd.Series(range(5), index = ['a', 'b', 'c', 'd', 'e'])
運行結果:
2. 行索引
ser_obj[‘label’], ser_obj[pos]
示例代碼:
運行結果:
3. 切片索引
ser_obj[2:4], ser_obj[‘label1’: ’label3’]
注意,按索引名切片操作時,是包含終止索引的。
示例代碼:
運行結果:
4. 不連續(xù)索引
ser_obj[[‘label1’, ’label2’, ‘label3’]]
示例代碼:
print(ser_obj[[0, 2, 4]]) print(ser_obj[['a', 'e']])
運行結果:
5. 布爾索引
示例代碼:
print(ser_obj[ser_obj > 2])
運行結果:
DataFrame索引
1. columns 指定列索引名
示例代碼:
df_obj = pd.DataFrame(np.random.randn(5,4), columns = ['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類型 print(df_obj[[0]]) # 返回DataFrame類型 print(type(df_obj[[0]])) # 返回DataFrame類型
運行結果:
<class 'pandas.core.frame.DataFrame'>
3. 不連續(xù)索引
df_obj[[‘label1’, ‘label2’]]
示例代碼:
運行結果:
高級索引:標簽、位置和混合
Pandas的高級索引有3種
1. loc 標簽索引
DataFrame 不能直接切片,可以通過loc來做切片
loc是基于標簽名的索引,也就是我們自定義的索引名
示例代碼:
print(ser_obj.loc['b':'d']) # 第一個參數(shù)索引行,第二個參數(shù)是列 print(df_obj.loc[0:2, 'a'])
運行結果:
2. iloc 位置索引
作用和loc一樣,不過是基于索引編號來索引
示例代碼:
print(df_obj.iloc[0:2, 0]) # 注意和df_obj.loc[0:2, 'a']的區(qū)別
運行結果:
3. ix 標簽與位置混合索引
ix是以上二者的綜合,既可以使用索引編號,又可以使用自定義索引,要視情況不同來使用,
如果索引既有數(shù)字又有英文,那么這種方式是不建議使用的,容易導致定位的混亂。
示例代碼:
print(ser_obj.ix['b':'c']) print(df_obj.loc[0:2, 'a'])
運行結果:
注意
DataFrame索引操作,可將其看作ndarray的索引操作
標簽的切片索引是包含末尾位置的
Pandas的對齊運算
是數(shù)據(jù)清洗的重要過程,可以按索引對齊進行運算,如果沒對齊的位置則補NaN,最后也可以填充NaN
Series的對齊運算
1. Series 按行、索引對齊
示例代碼:
s1 = pd.Series(range(10, 20), index = range(10)) s2 = pd.Series(range(20, 25), index = range(5))
運行結果:
2. Series的對齊運算
示例代碼:
運行結果:
DataFrame的對齊運算
1. DataFrame按行、列索引對齊
示例代碼:
df1 = pd.DataFrame(np.ones((2,2)), columns = ['a', 'b']) df2 = pd.DataFrame(np.ones((3,3)), columns = ['a', 'b', 'c'])
運行結果:
2. DataFrame的對齊運算
示例代碼:
運行結果:
填充未對齊的數(shù)據(jù)進行運算
1. fill_value
使用add , sub , div , mul 的同時,
通過fill_value 指定填充值,未對齊的數(shù)據(jù)將和填充值做運算
示例代碼:
s1.add(s2, fill_value = -1) df1.sub(df2, fill_value = 2.)
運行結果:
# s1.add(s2, fill_value = -1) # df1.sub(df2, fill_value = 2.)
Pandas的函數(shù)應用
apply 和 applymap
1. 可直接使用NumPy的函數(shù)
示例代碼:
df = pd.DataFrame(np.random.randn(5,4) - 1)
運行結果:
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 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將函數(shù)應用到列或行上
示例代碼:
# 使用apply應用行或列數(shù)據(jù) print(df.apply(lambda x : x.max()))
運行結果:
注意指定軸的方向,默認axis=0,方向是列
示例代碼:
print(df.apply(lambda x : x.max(), axis=1))
運行結果:
3. 通過applymap將函數(shù)應用到每個數(shù)據(jù)上
示例代碼:
# 使用applymap應用到每個數(shù)據(jù) f2 = lambda x : '%.2f' % x
運行結果:
1 -0.54 -1.98 -0.86 -2.61
排序
1. 索引排序
sort_index()
排序默認使用升序排序,ascending=False 為降序排序
示例代碼:
s4 = pd.Series(range(10, 15), index = np.random.randint(5, size=5)) s4.sort_index() # 0 0 1 3 3
運行結果:
對DataFrame操作時注意軸方向
示例代碼:
df4 = pd.DataFrame(np.random.randn(3, 5), index=np.random.randint(3, size=3), columns=np.random.randint(5, size=5)) df4_isort = df4.sort_index(axis=1, ascending=False) print(df4_isort) # 4 2 1 1 0
運行結果:
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 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')
根據(jù)某個唯一的列名進行排序,如果有其他相同列名則報錯。
示例代碼:
df4_vsort = df4.sort_values(by=0, ascending=False)
運行結果:
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
處理缺失數(shù)據(jù)
示例代碼:
df_data = pd.DataFrame([np.random.randn(3), [1., 2., np.nan], [np.nan, 4., np.nan], [1., 2., 3.]])
運行結果:
0 -0.281885 -0.786572 0.487126 3 1.000000 2.000000 3.000000
1. 判斷是否存在缺失值:isnull()
示例代碼:
運行結果:
2. 丟棄缺失數(shù)據(jù):dropna()
根據(jù)axis軸方向,丟棄包含NaN的行或列。 示例代碼:
print(df_data.dropna(axis=1))
運行結果:
0 -0.281885 -0.786572 0.487126 3 1.000000 2.000000 3.000000
3. 填充缺失數(shù)據(jù):fillna()
示例代碼:
print(df_data.fillna(-100.))
運行結果:
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
層級索引(hierarchical indexing)
下面創(chuàng)建一個Series, 在輸入索引Index時,輸入了由兩個子list組成的list,第一個子list是外層索引,第二個list是內層索引。
示例代碼:
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]
運行結果:
MultiIndex索引對象
-
打印這個Series的索引類型,顯示是MultiIndex
-
直接將索引打印出來,可以看到有l(wèi)avels,和labels兩個信息。lavels表示兩個層級中分別有那些標簽,labels是每個位置分別是什么標簽。
示例代碼:
print(type(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]])
選取子集
1. 外層選?。?/p>
ser_obj['outer_label']
示例代碼:
運行結果:
2. 內層選?。?/p>
ser_obj[:, 'inner_label']
示例代碼:
運行結果:
常用于分組操作、透視表的生成等
交換分層順序
1. swaplevel()
.swaplevel( )交換內層與外層索引。
示例代碼:
print(ser_obj.swaplevel())
運行結果:
交換并排序分層
sortlevel()
.sortlevel( )先對外層索引進行排序,再對內層索引進行排序,默認是升序。
示例代碼:
print(ser_obj.swaplevel().sortlevel())
運行結果:
Pandas統(tǒng)計計算和描述
示例代碼:
df_obj = pd.DataFrame(np.random.randn(5,4), columns = ['a', 'b', 'c', 'd'])
運行結果:
0 1.469682 1.948965 1.373124 -0.564129 1 -1.466670 -0.494591 0.467787 -2.007771 2 1.368750 0.532142 0.487862 -1.130825 3 -0.758540 -0.479684 1.239135 1.073077 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
示例代碼:
df_obj.min(axis=1, skipna=False)
運行結果:
常用的統(tǒng)計描述
describe 產生多個統(tǒng)計數(shù)據(jù)
示例代碼:
print(df_obj.describe())
運行結果:
count 5.000000 5.000000 5.000000 5.000000 mean 0.180305 0.106488 0.244978 0.178046 std 0.641945 0.454340 1.064356 1.144416 min -0.677175 -0.490278 -1.164928 -1.574556 25% -0.064069 -0.182920 -0.464013 -0.089962 50% 0.231722 0.127846 0.355859 0.190482 75% 0.318854 0.463377 1.169750 0.983663 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
-
拆分:進行分組的根據(jù)
-
應用:每個分組運行的計算規(guī)則
-
合并:把每個分組的計算結果合并起來
示例代碼:
dict_obj = {'key1' : ['a', 'b', 'a', 'b', 'key2' : ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], 'data1': np.random.randn(8), 'data2': np.random.randn(8)} df_obj = pd.DataFrame(dict_obj)
運行結果:
0 0.974685 -0.672494 a one 1 -0.214324 0.758372 b one 2 1.508838 0.392787 a two 3 0.522911 0.630814 b three 4 1.347359 -0.177858 a two 5 -0.264616 1.017155 b two 6 -0.624708 0.450885 a one 7 -1.019229 -1.143825 a three
一、GroupBy對象:DataFrameGroupBy,SeriesGroupBy
1. 分組操作
groupby()進行分組,GroupBy對象沒有進行實際運算,只是包含分組的中間數(shù)據(jù)
按列名分組:obj.groupby(‘label’)
示例代碼:
# dataframe根據(jù)key1進行分組 print(type(df_obj.groupby('key1'))) # dataframe的 data1 列根據(jù) key1 進行分組 print(type(df_obj['data1'].groupby(df_obj['key1'])))
運行結果:
<class 'pandas.core.groupby.DataFrameGroupBy'> <class 'pandas.core.groupby.SeriesGroupBy'>
2. 分組運算
對GroupBy對象進行分組運算/多重分組運算,如mean()
非數(shù)值數(shù)據(jù)不進行分組運算
示例代碼:
grouped1 = df_obj.groupby('key1') grouped2 = df_obj['data1'].groupby(df_obj['key1'])
運行結果:
Name: data1, dtype: float64
size() 返回每個分組的元素個數(shù)
示例代碼:
運行結果:
3. 按自定義的key分組
obj.groupby(self_def_key)
自定義的key可為列表或多層列表
obj.groupby([‘label1’, ‘label2’])->多層dataframe
示例代碼:
self_def_key = [0, 1, 2, 3, 3, 4, 5, 7] print(df_obj.groupby(self_def_key).size()) print(df_obj.groupby([df_obj['key1'], df_obj['key2']]).size()) grouped2 = df_obj.groupby(['key1', 'key2']) grouped3 = df_obj.groupby(['key2', 'key1']) # unstack可以將多層索引的結果轉換成單層的dataframe print(grouped3.mean().unstack())
運行結果:
three a -1.019229 -1.143825 one 0.174988 -0.214324 -0.110804 0.758372 three -1.019229 0.522911 -1.143825 0.630814 two 1.428099 -0.264616 0.107465 1.017155
二、GroupBy對象支持迭代操作
每次迭代返回一個元組 (group_name, group_data)
可用于分組數(shù)據(jù)的具體運算
1. 單層分組
示例代碼:
for group_name, group_data in grouped1:
運行結果:
0 0.974685 -0.672494 a one 2 1.508838 0.392787 a two 4 1.347359 -0.177858 a two 6 -0.624708 0.450885 a one 7 -1.019229 -1.143825 a three 1 -0.214324 0.758372 b one 3 0.522911 0.630814 b three 5 -0.264616 1.017155 b two
2. 多層分組
示例代碼:
for group_name, group_data in grouped2:
運行結果:
0 0.974685 -0.672494 a one 6 -0.624708 0.450885 a one 7 -1.019229 -1.143825 a three 2 1.508838 0.392787 a two 4 1.347359 -0.177858 a two 1 -0.214324 0.758372 b one 3 0.522911 0.630814 b three 5 -0.264616 1.017155 b two
三、GroupBy對象可以轉換成列表或字典
示例代碼:
print(dict(list(grouped1)))
運行結果:
[('a', data1 data2 key1 key2 0 0.974685 -0.672494 a one 2 1.508838 0.392787 a two 4 1.347359 -0.177858 a two 6 -0.624708 0.450885 a one 7 -1.019229 -1.143825 a three), ('b', data1 data2 key1 key2 1 -0.214324 0.758372 b one 3 0.522911 0.630814 b three 5 -0.264616 1.017155 b two)] {'a': data1 data2 key1 key2 0 0.974685 -0.672494 a one 2 1.508838 0.392787 a two 4 1.347359 -0.177858 a two 6 -0.624708 0.450885 a one 7 -1.019229 -1.143825 a three, 'b': data1 data2 key1 key2 1 -0.214324 0.758372 b one 3 0.522911 0.630814 b three 5 -0.264616 1.017155 b two}
1. 按列分組、按數(shù)據(jù)類型分組
示例代碼:
print(df_obj.groupby(df_obj.dtypes, axis=1).size()) print(df_obj.groupby(df_obj.dtypes, axis=1).sum())
運行結果:
2. 其他分組方法
示例代碼:
df_obj2 = pd.DataFrame(np.random.randint(1, 10, (5,5)), columns=['a', 'b', 'c', 'd', 'e'], index=['A', 'B', 'C', 'D', 'E']) df_obj2.ix[1, 1:4] = np.NaN
運行結果:
3. 通過字典分組
示例代碼:
mapping_dict = {'a':'Python', 'b':'Python', 'c':'Java', 'd':'C', 'e':'Java'} print(df_obj2.groupby(mapping_dict, axis=1).size()) print(df_obj2.groupby(mapping_dict, axis=1).count()) # 非NaN的個數(shù) print(df_obj2.groupby(mapping_dict, axis=1).sum())
運行結果:
4. 通過函數(shù)分組,函數(shù)傳入的參數(shù)為行索引或列索引
示例代碼:
df_obj3 = pd.DataFrame(np.random.randint(1, 10, (5,5)), columns=['a', 'b', 'c', 'd', 'e'], index=['AA', 'BBB', 'CC', 'D', 'EE']) print(df_obj3.groupby(group_key).size()) #df_obj3.groupby(len).size()
運行結果:
5. 通過索引級別分組
示例代碼:
columns = pd.MultiIndex.from_arrays([['Python', 'Java', 'Python', 'Java', 'Python'], ['A', 'A', 'B', 'C', 'B']], names=['language', 'index']) df_obj4 = pd.DataFrame(np.random.randint(1, 10, (5, 5)), columns=columns) print(df_obj4.groupby(level='language', axis=1).sum()) print(df_obj4.groupby(level='index', axis=1).sum())
運行結果:
language Python Java Python Java Python
聚合 (aggregation)
示例代碼:
dict_obj = {'key1' : ['a', 'b', 'a', 'b', 'key2' : ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], 'data1': np.random.randint(1,10, 8), 'data2': np.random.randint(1,10, 8)} df_obj5 = pd.DataFrame(dict_obj)
運行結果:
1. 內置的聚合函數(shù)
sum(), mean(), max(), min(), count(), size(), describe()
示例代碼:
print(df_obj5.groupby('key1').sum()) print(df_obj5.groupby('key1').max()) print(df_obj5.groupby('key1').min()) print(df_obj5.groupby('key1').mean()) print(df_obj5.groupby('key1').size()) print(df_obj5.groupby('key1').count()) print(df_obj5.groupby('key1').describe())
運行結果:
a count 5.000000 5.000000 b count 3.000000 3.000000
2. 可自定義函數(shù),傳入agg方法中
grouped.agg(func)
func的參數(shù)為groupby索引對應的記錄
示例代碼:
#print type(df) #參數(shù)為索引所對應的記錄 return df.max() - df.min() print(df_obj5.groupby('key1').agg(peak_range)) print(df_obj.groupby('key1').agg(lambda df : df.max() - df.min()))
運行結果:
3. 應用多個聚合函數(shù)
同時應用多個函數(shù)進行聚合操作,使用函數(shù)列表
示例代碼:
print(df_obj.groupby('key1').agg(['mean', 'std', 'count', peak_range])) # 默認列名為函數(shù)名 print(df_obj.groupby('key1').agg(['mean', 'std', 'count', ('range', peak_range)])) # 通過元組提供新的列名
運行結果:
mean std count peak_range mean std count peak_range a 0.437389 1.174151 5 2.528067 -0.230101 0.686488 5 1.594711 b 0.014657 0.440878 3 0.787527 0.802114 0.196850 3 0.386341 mean std count range mean std count range a 0.437389 1.174151 5 2.528067 -0.230101 0.686488 5 1.594711 b 0.014657 0.440878 3 0.787527 0.802114 0.196850 3 0.386341
4. 對不同的列分別作用不同的聚合函數(shù),使用dict
示例代碼:
dict_mapping = {'data1':'mean', print(df_obj.groupby('key1').agg(dict_mapping)) dict_mapping = {'data1':['mean','max'], print(df_obj.groupby('key1').agg(dict_mapping))
運行結果:
a 0.437389 1.508838 -1.150505 b 0.014657 0.522911 2.406341
5. 常用的內置聚合函數(shù)
數(shù)據(jù)的分組運算
示例代碼:
dict_obj = {'key1' : ['a', 'b', 'a', 'b', 'key2' : ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], 'data1': np.random.randint(1, 10, 8), 'data2': np.random.randint(1, 10, 8)} df_obj = pd.DataFrame(dict_obj) # 按key1分組后,計算data1,data2的統(tǒng)計信息并附加到原始表格中,并添加表頭前綴 k1_sum = df_obj.groupby('key1').sum().add_prefix('sum_')
運行結果:
聚合運算后會改變原始數(shù)據(jù)的形狀,
如何保持原始數(shù)據(jù)的形狀?
1. merge
使用merge的外連接,比較復雜
示例代碼:
k1_sum_merge = pd.merge(df_obj, k1_sum, left_on='key1', right_index=True)
運行結果:
data1 data2 key1 key2 sum_data1 sum_data2
2. transform
transform的計算結果和原始數(shù)據(jù)的形狀保持一致,
如:grouped.transform(np.sum)
示例代碼:
k1_sum_tf = df_obj.groupby('key1').transform(np.sum).add_prefix('sum_') df_obj[k1_sum_tf.columns] = k1_sum_tf
運行結果:
data1 data2 key1 key2 sum_data1 sum_data2 sum_key2 0 5 1 a one 26 26 onetwotwoonethree 1 7 8 b one 17 17 onethreetwo 2 1 9 a two 26 26 onetwotwoonethree 3 2 6 b three 17 17 onethreetwo 4 9 8 a two 26 26 onetwotwoonethree 5 8 3 b two 17 17 onethreetwo 6 3 5 a one 26 26 onetwotwoonethree 7 8 3 a three 26 26 onetwotwoonethree
也可傳入自定義函數(shù),
示例代碼:
print(df_obj.groupby('key1').transform(diff_mean))
運行結果:
data1 data2 sum_data1 sum_data2 0 -0.200000 -4.200000 0 0 6 -2.200000 -0.200000 0 0
groupby.apply(func)
func函數(shù)也可以在各分組上分別調用,最后結果通過pd.concat組裝到一起(數(shù)據(jù)合并)
示例代碼:
dataset_path = './starcraft.csv' df_data = pd.read_csv(dataset_path, usecols=['LeagueIndex', 'Age', 'HoursPerWeek', def top_n(df, n=3, column='APM'): 返回每個分組按 column 的 top n 數(shù)據(jù) return df.sort_values(by=column, ascending=False)[:n] print(df_data.groupby('LeagueIndex').apply(top_n))
運行結果:
LeagueIndex Age HoursPerWeek TotalHours APM 1 2214 1 20.0 12.0 730.0 172.9530 2246 1 27.0 8.0 250.0 141.6282 1753 1 20.0 28.0 100.0 139.6362 2 3062 2 20.0 6.0 100.0 179.6250 3229 2 16.0 24.0 110.0 156.7380 1520 2 29.0 6.0 250.0 151.6470 3 1557 3 22.0 6.0 200.0 226.6554 484 3 19.0 42.0 450.0 220.0692 2883 3 16.0 8.0 800.0 208.9500 4 2688 4 26.0 24.0 990.0 249.0210 1759 4 16.0 6.0 75.0 229.9122 2637 4 23.0 24.0 650.0 227.2272 5 3277 5 18.0 16.0 950.0 372.6426 93 5 17.0 36.0 720.0 335.4990 202 5 37.0 14.0 800.0 327.7218 6 734 6 16.0 28.0 730.0 389.8314 2746 6 16.0 28.0 4000.0 350.4114 1810 6 21.0 14.0 730.0 323.2506 7 3127 7 23.0 42.0 2000.0 298.7952 104 7 21.0 24.0 1000.0 286.4538 1654 7 18.0 98.0 700.0 236.0316 8 3393 8 NaN NaN NaN 375.8664 3373 8 NaN NaN NaN 364.8504 3372 8 NaN NaN NaN 355.3518
1. 產生層級索引:外層索引是分組名,內層索引是df_obj的行索引
示例代碼:
# apply函數(shù)接收的參數(shù)會傳入自定義的函數(shù)中 print(df_data.groupby('LeagueIndex').apply(top_n, n=2, column='Age'))
運行結果:
LeagueIndex Age HoursPerWeek TotalHours APM 1 3146 1 40.0 12.0 150.0 38.5590 3040 1 39.0 10.0 500.0 29.8764 2 920 2 43.0 10.0 730.0 86.0586 2437 2 41.0 4.0 200.0 54.2166 3 1258 3 41.0 14.0 800.0 77.6472 2972 3 40.0 10.0 500.0 60.5970 4 1696 4 44.0 6.0 500.0 89.5266 1729 4 39.0 8.0 500.0 86.7246 5 202 5 37.0 14.0 800.0 327.7218 2745 5 37.0 18.0 1000.0 123.4098 6 3069 6 31.0 8.0 800.0 133.1790 2706 6 31.0 8.0 700.0 66.9918 7 2813 7 26.0 36.0 1300.0 188.5512 1992 7 26.0 24.0 1000.0 219.6690 8 3340 8 NaN NaN NaN 189.7404 3341 8 NaN NaN NaN 287.8128
2. 禁止層級索引, group_keys=False
示例代碼:
print(df_data.groupby('LeagueIndex', group_keys=False).apply(top_n))
運行結果:
LeagueIndex Age HoursPerWeek TotalHours APM 2214 1 20.0 12.0 730.0 172.9530 2246 1 27.0 8.0 250.0 141.6282 1753 1 20.0 28.0 100.0 139.6362 3062 2 20.0 6.0 100.0 179.6250 3229 2 16.0 24.0 110.0 156.7380 1520 2 29.0 6.0 250.0 151.6470 1557 3 22.0 6.0 200.0 226.6554 484 3 19.0 42.0 450.0 220.0692 2883 3 16.0 8.0 800.0 208.9500 2688 4 26.0 24.0 990.0 249.0210 1759 4 16.0 6.0 75.0 229.9122 2637 4 23.0 24.0 650.0 227.2272 3277 5 18.0 16.0 950.0 372.6426 93 5 17.0 36.0 720.0 335.4990 202 5 37.0 14.0 800.0 327.7218 734 6 16.0 28.0 730.0 389.8314 2746 6 16.0 28.0 4000.0 350.4114 1810 6 21.0 14.0 730.0 323.2506 3127 7 23.0 42.0 2000.0 298.7952 104 7 21.0 24.0 1000.0 286.4538 1654 7 18.0 98.0 700.0 236.0316 3393 8 NaN NaN NaN 375.8664 3373 8 NaN NaN NaN 364.8504 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)
示例代碼:
df_obj1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'], 'data1' : np.random.randint(0,10,7)}) df_obj2 = pd.DataFrame({'key': ['a', 'b', 'd'], 'data2' : np.random.randint(0,10,3)})
運行結果:
1. 默認將重疊列的列名作為“外鍵”進行連接
示例代碼:
print(pd.merge(df_obj1, df_obj2))
運行結果:
2. on顯示指定“外鍵”
示例代碼:
print(pd.merge(df_obj1, df_obj2, on='key'))
運行結果:
3. left_on,左側數(shù)據(jù)的“外鍵”,right_on,右側數(shù)據(jù)的“外鍵”
示例代碼:
# left_on,right_on分別指定左側數(shù)據(jù)和右側數(shù)據(jù)的“外鍵” df_obj1 = df_obj1.rename(columns={'key':'key1'}) df_obj2 = df_obj2.rename(columns={'key':'key2'}) print(pd.merge(df_obj1, df_obj2, left_on='key1', right_on='key2'))
運行結果:
默認是“內連接”(inner),即結果中的鍵是交集
how 指定連接方式
4. “外連接”(outer),結果中的鍵是并集
示例代碼:
print(pd.merge(df_obj1, df_obj2, left_on='key1', right_on='key2', how='outer'))
運行結果:
5. “左連接”(left)
示例代碼:
print(pd.merge(df_obj1, df_obj2, left_on='key1', right_on='key2', how='left'))
運行結果:
6. “右連接”(right)
示例代碼:
print(pd.merge(df_obj1, df_obj2, left_on='key1', right_on='key2', how='right'))
運行結果:
7. 處理重復列名
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')))
運行結果:
8. 按索引連接
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))
運行結果:
數(shù)據(jù)合并(pd.concat)
1. NumPy的concat
np.concatenate
示例代碼:
arr1 = np.random.randint(0, 10, (3, 4)) arr2 = np.random.randint(0, 10, (3, 4)) print(np.concatenate([arr1, arr2])) print(np.concatenate([arr1, arr2], axis=1))
運行結果:
# print(np.concatenate([arr1, arr2])) # print(np.concatenate([arr1, arr2], axis=1))
2. pd.concat
-
注意指定軸方向,默認axis=0
-
join指定合并方式,默認為outer
-
Series合并時查看行索引有無重復
1) index 沒有重復的情況
示例代碼:
ser_obj1 = pd.Series(np.random.randint(0, 10, 5), index=range(0,5)) ser_obj2 = pd.Series(np.random.randint(0, 10, 4), index=range(5,9)) ser_obj3 = pd.Series(np.random.randint(0, 10, 3), index=range(9,12)) print(pd.concat([ser_obj1, ser_obj2, ser_obj3])) print(pd.concat([ser_obj1, ser_obj2, ser_obj3], axis=1))
運行結果:
# print(pd.concat([ser_obj1, ser_obj2, ser_obj3])) # print(pd.concat([ser_obj1, ser_obj2, ser_obj3], axis=1))
2) index 有重復的情況
示例代碼:
ser_obj1 = pd.Series(np.random.randint(0, 10, 5), index=range(5)) ser_obj2 = pd.Series(np.random.randint(0, 10, 4), index=range(4)) ser_obj3 = pd.Series(np.random.randint(0, 10, 3), index=range(3)) print(pd.concat([ser_obj1, ser_obj2, ser_obj3]))
運行結果:
# print(pd.concat([ser_obj1, ser_obj2, ser_obj3])) # print(pd.concat([ser_obj1, ser_obj2, ser_obj3], axis=1, join='inner')) # join='inner' 將去除NaN所在的行或列
3) DataFrame合并時同時查看行索引和列索引有無重復
示例代碼:
df_obj1 = pd.DataFrame(np.random.randint(0, 10, (3, 2)), index=['a', 'b', 'c'], df_obj2 = pd.DataFrame(np.random.randint(0, 10, (2, 2)), index=['a', 'b'], print(pd.concat([df_obj1, df_obj2])) print(pd.concat([df_obj1, df_obj2], axis=1, join='inner'))
運行結果:
# print(pd.concat([df_obj1, df_obj2])) # print(pd.concat([df_obj1, df_obj2], axis=1, join='inner'))
數(shù)據(jù)重構
1. stack
-
將列索引旋轉為行索引,完成層級索引
-
DataFrame->Series
示例代碼:
df_obj = pd.DataFrame(np.random.randint(0,10, (5,2)), columns=['data1', 'data2'])
運行結果:
2. unstack
-
將層級索引展開
-
Series->DataFrame
-
認操作內層索引,即level=-1
示例代碼:
print(stacked.unstack(level=0))
運行結果:
# print(stacked.unstack()) # print(stacked.unstack(level=0))
數(shù)據(jù)轉換
一、 處理重復數(shù)據(jù)
1 duplicated() 返回布爾型Series表示每行是否為重復行
示例代碼:
df_obj = pd.DataFrame({'data1' : ['a'] * 4 + ['b'] * 4, 'data2' : np.random.randint(0, 4, 8)}) print(df_obj.duplicated())
運行結果:
# print(df_obj.duplicated())
2 drop_duplicates() 過濾重復行
默認判斷全部列
可指定按某些列判斷
示例代碼:
print(df_obj.drop_duplicates()) print(df_obj.drop_duplicates('data2'))
運行結果:
# print(df_obj.drop_duplicates()) # print(df_obj.drop_duplicates('data2'))
3. 根據(jù)map 傳入的函數(shù)對每行或每列進行轉換
- Series根據(jù)
map 傳入的函數(shù)對每行或每列進行轉換
示例代碼:
ser_obj = pd.Series(np.random.randint(0,10,10)) print(ser_obj.map(lambda x : x ** 2))
運行結果:
# print(ser_obj.map(lambda x : x ** 2))
二、數(shù)據(jù)替換
replace 根據(jù)值的內容進行替換
示例代碼:
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)) # print(ser_obj.replace([6, 8], -100)) # print(ser_obj.replace([4, 7], [-100, -200]))
聚類模型:K-Means
K-Means算法
算法思想:
以空間中k個樣本點為中心進行聚類,對最靠近它們的樣本點歸類。通過迭 代的方法,逐步更新各聚類中心,直至達到最好的聚類效果
算法描述:
- 選擇k個聚類的初始中心
- 在第n次迭代中,對任意一個樣本點,求其到k個聚類中心的距離,將該 樣本點歸類到距離最小的中心所在的聚類
- 利用均值等方法更新各類的中心值
- 對所有的k個聚類中心,如果利用2,3步的迭代更新后,達到穩(wěn)定,則迭代 結束。
優(yōu)缺點:
全球食品數(shù)據(jù)分析
項目參考:https://www./bhouwens/d/openfoodfacts/world-food-facts/how-much-sugar-do-we-eat/discussion
import matplotlib.pyplot as plt def unzip(zip_filepath, dest_path): with zipfile.ZipFile(zip_filepath) as zf: zf.extractall(path=dest_path) def get_dataset_filename(zip_filepath): with zipfile.ZipFile(zip_filepath) as zf: dataset_path = './data' # 數(shù)據(jù)集路徑 zip_filename = 'open-food-facts.zip' # zip文件名 zip_filepath = os.path.join(dataset_path, zip_filename) # zip文件路徑 dataset_filename = get_dataset_filename(zip_filepath) # 數(shù)據(jù)集文件名(在zip中) dataset_filepath = os.path.join(dataset_path, dataset_filename) # 數(shù)據(jù)集文件路徑 print('解壓zip...', end='') unzip(zip_filepath, dataset_path) data = pd.read_csv(dataset_filepath, usecols=['countries_en', 'additives_n']) # 分析各國家食物中的食品添加劑種類個數(shù) data = data.dropna() # 或者data.dropna(inplace=True) # 課后練習:經過觀察發(fā)現(xiàn)'countries_en'中的數(shù)值不是單獨的國家名稱, # 有的是多個國家名稱用逗號隔開,如 Albania,Belgium,France,Germany,Italy,Netherlands,Spain # 正確的統(tǒng)計應該是將這些值拆開成多個行記錄,然后進行分組統(tǒng)計 data['countries_en'] = data['countries_en'].str.lower() # 2. 數(shù)據(jù)分組統(tǒng)計 country_additives = data['additives_n'].groupby(data['countries_en']).mean() result = country_additives.sort_values(ascending=False) result.iloc[:10].plot.bar() result.to_csv('./country_additives.csv') if os.path.exists(dataset_filepath): os.remove(dataset_filepath) if __name__ == '__main__':
|