Python數據分析常用API整理

整理歸納在Python中使用對數據處理的常用方法,包括與HDFS文件的讀寫,主要是怕用的時候記不住,容易搞混,再搜也不爽,好記性不如爛筆頭,寫下來自己用的時候方便看,而且寫一遍也加深印象。
隨查隨用隨更新

Numpy

ndarray

ndarr1 = np.array([ [1, 2, 3], [4, 5, 6] ])
shape 大小和形狀
dtype 數據類型
astype 顯式的轉換類型
不同大小的ndarray也可以運算,稱之為廣播,比如arr * 2
一維:用[x]進行索引,用[x:y]進行切片,都是原始數組的視圖
多維:[x][y]或者[x,y]索引,[x1:x2, y1:y2]切片
布爾型可以直接做索引

按軸進行布爾類型list的索引,或者對每個元素進行單個布爾索引,比如data1[data1 > 0] = 0

花式索引行和列

arr[ [行1, 行i] ][ :, [列1, 列i] ] 或者
arr[ np.ix_( [行1, 行i], [列1, 列i] ) ]
而且花式索引總是復制數據到新的數組中,不是切片那種原始數組的視圖

arr.T 轉置
通用函數

np.sqrt(arr) arr的開平方
np.exp(arr) arr的e的x次方
np.abs(arr) arr的絕對值
np.square(arr) arr的平方
np.log(arr) ln(arr)
np.log10(arr) log10(arr)
np.isnan arr的各個元素是否為NaN的bool數組
np.add(arr1, arr2) arr1 + arr2
np.subtract(arr1, arr2) arr1 - arr2

三元表達式
np.where(cond, xarr, yarr) 等價為 xarr if cond else yarr
統計

arr.sum(axis=?) 按照軸的方向求和
arr.mean 按照軸的方向求平均值
arr.min()和max() 最大和最小值
arr.argmin()和argmax() 最大和最小值的索引
arr.cumsum() 所有元素的累計和
arr.cumprod() 所有元素的累計積
排序
np.sort(arr)和arr.sort(),前者是頂級方法,返回對arr排序后的副本;后者則是直接對arr排序。

線性代數
包括矩陣的點乘,矩陣分解以及行列式等等。
點乘:xarr.dot(yarr)等價于np.dot(xarr, yarr)
numpy.linalg中有一組標準的矩陣分解運算以及諸如求逆和行列式之類。比如如下部分:

diag([一維數組]) 對角矩陣,對角線是輸入的一維數組
dot 點乘
det 計算矩陣的行列式
inv 計算矩陣的逆
qr 計算QR分解
svd 計算奇異值分解(SVD)

Pandas

(官網)https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.html
官網Pandas的API匯總
官網10分鐘對Pandas的簡介

Series

可以把Series看成是一個有序的定長字典。
ser = Series([1, 2, 3, 4], index=['d', 'b', 'a', 'c'])
經常存在與DataFrame的行與列中。
也可以直接從字典類型的對象中構建。
idx_val_map = {'d':1, 'b':2, 'a':3, 'c':4}
ser = Series(idx_val_map, name='值的名稱')
ser.index.name = '索引的名稱'
ser['a']進行索引
再進一步,比如對于二維的DataFrame,取其中一列出來,就是Series,它的name就是這一列的名字,它的index就是DataFrame的index,index的name就是DataFrame中作為index的那一列的名字。

DataFrame

DataFrame的索引是不可更改的。可以添加和刪除,但是不能修改。

  • 構造DataFrame
    1.由二維ndarray構造,可以給出行標和列標
    result1 = pd.DataFrame([[1, 0.7], [0, 0.7]], index=pd.Index([135, 136], name='Number'), columns=['Gender', 'Prob'])
    
    2.由字典構成,外層字典key是列標,內層字典是行標
    需要注意的是字典構成的df,需要指定column的順序,否則默認會按照列的字符串名排序
predict_df = pd.DataFrame(data={'svc_y': svc_y, 'dnn_y': dnn_y, 'xgb_y': xgb_y, 'rf_y': rf_y}, columns=['svc_y', 'dnn_y', 'xgb_y' ,'rf_y'])

3.由另一個DataFrame構成
有時候會有一種需求是從已經有的DataFrame中創建一個空的Dataframe但是使用的是原來這個Dataframe的結構。

copy_df = pd.DataFrame.from_items([(name, pd.Series(data=None, dtype=series.dtype)) 
                                    for name, series in original_df.iteritems()])
  • 添加列

    frame['new-col'] = value
    # 需要添加多列時比較特殊點需要借Dataframe來賦值
    frame[['new-col1', ..., 'new-coln']] = pd.Dataframe(np.random.randint(1,5,[n_rows, n]), index=frame.index)
    
  • 添加行

    s = pd.Series({'Col1':'Value1', 'Col2': 'Value2', 'Col3': Value3})  # 構造一行新數據
    frame.append(s)
    
  • 刪除列

    del frame['col-name']
    
  • 刪除行

    # 因為DataFrame是列索引的(在frame.items()返回值中可以看出來)所以del只能刪除列,刪除行需要用到drop方法
    frame.drop(frame.index[[1,3]])
    
  • 索引方式
    列索引:frame['col_name']或者frame.col_name
    行索引:frame.ix['row_name']
    點索引:frame.at[行,列] 或者frame.iat[行i,列i],只能索引具體的元素,不能切片
    用整數位置索引frame.iloc[index(列表), col-index(列表)]
    ix[行, 列]和iloc[行, 列]都可同時索引行與列,區別在于ix用的是名字(當DataFrame的index沒有設置時,退化成iloc),iloc用的是整數位置
    loc: works on labels in the index.
    iloc: works on the positions in the index (so it only takes integers).
    ix: usually tries to behave like loc but falls back to behaving like iloc if the label is not in the index.

    • 總結
      ['col-name']——是對列的索引
      [ ['col-name1', 'col-name_i'] ]——兩個[]是對多個列的索引
      [bool類型list]或者[i:j]——是對行的切片索引
      ix[行,列]——支持對行和列同時索引和切片(loc和iloc參考上面)NOTE:ix操作如果有左值,那么就默認會copy,如果沒有左值那么就是對原始Frame進行操作,而loc和iloc默認都是對原始Frame的操作,所以推薦使用loc,如果需要復制,可以顯式的調用Frame.copy(). 不過仍要注意的是frame2 = frame1.loc[a:d, :]確實不是復制是對原frame1的切片,但是frame1.loc[ [a, b, c, d], :]則是復制不是切片了。
      at[行,列]和iat[i,j]——是定位到元素
      所以對列的bool類型list切片應該用ix[:,bool_list],然而對行的bool類型list切片可以直接[bool_list]
  • 基本功能

    • 重新索引
      reindex,對索引重新排序,新加的使用缺失值填充。

    • 丟棄指定軸上的項
      frame.drop(['name'], axis=?)

    • 切片
      frame[:2] 這個是直接按行切片,和常識有點不太一樣,但是方便實際操作。
      frame[ ['列1', '列i'] ],這個是按列切片

    • 過濾
      按照某一列的值過濾:frame[ frame['列'] > 5 ]
      對于bool類型的list,除了上面的方法,也可以frame.loc[bool_list_X, bool_list_Y]進行過濾。

    • 算術運算
      frame1 + frame2 或者 frame1.add(frame2, fill_value=0)
      sub做減法 div是除法 mul是乘法

    • 函數應用和映射
      Numpy的ufuncs也可用于操作pandas對象

      np.abs(frame)

      還可以自定義函數(列或行的):

      f = lambda x: x.max() - x.min()
      frame.apply(f, axis=?)

      對元素的函數

      format = lambda x: '%.2f' % x
      frame.applymap(format)

      featQuant = sampleDF_feat.quantile(0.999) # 獲得0.999的分位數
      frameFeatUnderQuant = sampleDF_feat.where(sampleDF_feat <= featQuant, other=0) # 把異常高的數值排除掉

      總的來說,DataFrame可以用的是apply和applymap,Series可以用的是map:

      apply:是對DataFrame的具體行或者列進行整體操作。比如可以取最大最小值
      applymap:是對DataFrame的具體每個元素進行操作。
      map:也是對每個元素進行操作,和applymap類似。

    • 排序
      frame.sort_index(by='name', axis=?, ascending=True)

  • 匯總和計算描述

    frame.sum(axis=?, skipna=True) 求和
    frame.mean() 平均值
    frame.count()
    frame.min、max
    frame.argmin、argmax 整數索引位置
    frame.idmin、idmax 名字ID索引位置
    frame.quantile() 計算樣本的分位數(0到1),比如frame['col_name'].quantile([q/10 for q in range(1, 11, 1)])
    frame.describe() # 描述各個列的詳細統計信息
    frame.info() # 描述各個列是否有缺失值和dtype
    frame['col_name'].value_counts() # 計算得到col_name列上各種取值的個數

    • groupby
      這個操作是對數據做聚合后的操作。
      比如df['col1'].groupby(by=某種依據),就是在df的'col'列上按照某種依據來聚合,產生一個DataFrameGroupBy對象。這里的某種依據就是告訴pandas在聚合時哪幾個數據屬于一類的,比如df的行數為7,那么某種依據為['c','s','t','t','s','s','c'],會把第一行和最后一行歸在一起,第2\5\6行歸在一起,第3\4行歸在一起。
      此時可以使用mean(),sum(),apply()這樣的操作來得到想要的值。當對df['col1']做groupby時得到的每一項是Series,此時apply(lambda x: ...)中的x是Series類型;當對df[['col1',...,'colN']]做groupby時得到的是Dataframe,此時apply(lambda x: ...)中的x是DataFrame類型。
      比如對df['cnt']表示某個用戶購買某個物品的個數,我們想得到每個用戶各自購買物品占自己購買總數的比值時:df['cnt'].groupby(df['user_name']).apply(lambda cnts: cnts.apply(lambda n: n / cnts.sum()))
      另外df.groupby(...).agg(func)是指對df做group之后對每一列執行func,如果不需要對每列執行,則直接使用apply即可。agg的詳細示例見:官網agg
    • melt
      這個是讓df按照指定的列消融,比如df有3列,直接melt(),會得到新的melt_df由index, variable, value這三個列組成,其中index的范圍是原來的3倍,variable是原來的列名,value是原來對應列的值。
      melt()函數有幾個參數:id_vars='不消融的列', value_vars=消融的列list, var_name='消融后variable的名字', value_name='消融后value的名字'
  • 處理缺失數據

    frame.dropna() 丟棄NaN,可以給出閾值進行調節容忍度
    df.fillna( {'列1': 值1, '列i': 值i}, inplace=True ) 默認返回一個新的對象
    frame.isnull() 返回與frame一樣大小的布爾值對象(值為NaN的為True,否則為False)

  • 其他常用

    # 去重
    df.duplicated(keep='first')  # 這個會返回列的值重復與否的布爾值,默認對于重復值的第一個為False,其他重復的為True
    # 得到這個布爾后可以再進行切片去重,不過還有更便捷的方法:
    df['某列'].drop_duplicates(keep='first', inplace=True)  # 這樣直接得到去重后的結果。
    
  • 從文件中讀取
    frame = pd.read_csv('file.csv', names=col_names, index_col='col_index')
    另外說下,如果csv的文件中是這樣的0,1,2,"string:\"(1,2)\"",那么上面在讀的過程中會有問題,多讀出一列,需要加上參數escapechar="\\",也就是:
    frame = pd.read_csv('file.csv', names=col_names, index_col='col_index', escapechar="\\")
    除了讀取本地文件還可以讀取HDFS文件:

    首先需要安裝需要的包:pip install hdfs 官網文檔
    然后代碼中:

    from hdfs import Client
    from hdfs import HdfsError
    
    client = Client('http://name_node.url:50070')  # 輸入要鏈接的NameNode地址。如果是高可用的模式,會有多個name node,那么有個比較笨的方法就是挨個試,看看那個可用(也就是處于active狀態)就用哪個。
    
    print(client.list('/'))  # 可以在這里添加try操作,catch到異常后去嘗試下一個name node的鏈接。
    
    try:
        with client.read('path/file.csv') as hdfs_in_fs:
            predictDF = pd.read_csv(hdfs_in_fs, names=predict_cols, index_col='Number')
    except HdfsError as e:
        print(e)
    
  • 將Frame寫入文件
    frame.to_csv(path_or_buf='path/file', index=True, header=False, sep='|')
    寫入HDFS文件會有些麻煩,一是寫的時候需要權限,把要寫入的目錄設置為hdfs dfs -chmod -R 777 write_Dir;二是寫入文件會遇到TypeError: a bytes-like object is required, not 'str',因為不像普通的文件可以在open的時候設置mode參數,所以還需要做如下操作:

    from hdfs import Client
    from hdfs import HdfsError
    
    client = Client('http://name_node.url:50070')  # 輸入要鏈接的NameNode地址。如果是高可用的模式,會有多個name node,那么有個比較笨的方法就是挨個試,看看那個可用(也就是處于active狀態)就用哪個。
    
    print(client.list('/'))  # 可以在這里添加try操作,catch到異常后去嘗試下一個name node的鏈接。
    
    try:
        with client.write('path/file' overwrite=True, encoding='utf-8') as hdfs_out_fs:  # 需要設置encoding不然遇到上面說的TypeError
            predictDF[['Gender', 'Prob']].to_csv(path_or_buf=hdfs_out_fs, index=True, header=False, sep='|')
    except HdfsError as e:
        print(e)
    
  • 另外一種讀寫HDFS文件的方法
    上面的代碼確實可以讀寫HDFS文件,不過需要修改權限,這會出現下面情況:

    可以看到為了允許讀寫,上級目錄已經將權限更改為全部可讀寫執行了,而且新創建的文件夾和文件都是用戶dr.who

    這會給后續操作帶來一定的麻煩,比如yarn用戶在程序中對這個文件無法修改。因為只有讀權限。
    不過還有一個API可以在python中使用,如果你的HDFS配置支持非安全的HttpFS的話。

    Client API介紹

    上面的使用Client的API是用的WebHDFS。連接的時候需要指定namenode,而在高可用的模式情況下,可能要多試幾次才知道當前哪個node處于active狀態。為了避免這兩個問題,接下來展示另外一個API InsecureClient來實現。在接下來的代碼中,使用的是HttpFS方式來讀寫HDFS

    from hdfs import InsecureClient
    
    client = InsecureClient('http://HttpFS_node.url:14000', user='yarn')  # 使用HttpFS所配置的角色主機域名及REST 端口
    
    print(client.list('/'))  # 無需像之前一樣多次嘗試當前輸入的namenode是否可用
    
    with client.read('path/in_file') as hdfs_in_fs:
        with client.write('path/out_file', overwrite=True, encoding='utf-8') as hdfs_out_fs:
            sampleDF = pd.read_csv(hdfs_in_fs, names=, index_col=)
            sampleDF.to_csv(path_or_buf=hdfs_out_fs, index=True, header=False, sep='|')
    

    這個API的好處是:1、不需要修改權限,由參數的指定用戶保證權限沒問題。2、新寫入的文件權限也無問題。3、可以支持遠程讀寫,無需在集群上執行,在本地PC上運行即可。4、無需知道當前active的namenode是哪個,可以通過HttpFS主機直接連接。

    新建的文件都是用戶yarn的
  • 合并數據集

    • pandas.merge
      根據一個或多個鍵將不同的DataFrame中的行連接起來。類似SQL的關系型數據庫的連接操作
      簡單說就是將多個DataFrame按照指定的各自的列以某種方式(inner,left,right,outer)組合起來。
      除了pd.merge還有frame_left.join(frame_right)這個方式
      其中join和merge的區別如下:
    left.join(right, on='col_name') #是將left的col_name列和right的index進行比較連接,且默認how='left'
    left.merge(right, on='col_name') #是將left和right共有的col_name列進行比較連接,且默認how='inner'
    # 不過如果right中如果沒有col_name列,那么還是會和join一樣會拿index來連接.
    # 另外merge還提供了left_on/right_on/left_index/right_index這些參數供選擇
    
    • pandas.concat
      沿著一條軸將多個對象堆疊在一起
      比如將兩個frame的行數據堆疊起來。
      frame_total = pd.concat([frame1, framei], axis=?, keys=['col1_name', 'coli_name'])
    • 舉栗
      合并Series到Dataframe中:
      purchase_1 = pd.Series({'Name': 'Chris',
                          'Item Purchased': 'Dog Food',
                          'Cost': 22.50})
      purchase_2 = pd.Series({'Name': 'Kevyn',
                          'Item Purchased': 'Kitty Litter',
                          'Cost': 2.50})
      purchase_3 = pd.Series({'Name': 'Vinod',
                          'Item Purchased': 'Bird Seed',
                          'Cost': 5.00})
      df = pd.DataFrame([purchase_1, purchase_2, purchase_3], index=['Store 1', 'Store 1', 'Store 2'])
      
      s = pd.Series({'Name':'Kevyn', 'Item Purchased': 'Kitty Food', 'Cost': 3.00})
      s.name = 'Store 2'
      
      # 合并s到df中
      # 方法1,使用concat函數
      df = pd.concat([df, s.to_frame().T])
      # 方法2,使用append
      df = df.append(s)
      
  • 打印DataFrame
    打印DataFrame非常簡單直接print就可以了,但是Pandas對于顯示的行數、列數、寬度和長度都有默認限制,如果不期望看到...這樣的省略號,或者不期望換行,那么可以如下設置:
    在最近的pandas版本中,已經沒有display.height這個參數了,其值可由display.max_rows自動推斷得到。

    pd.set_option('display.height',1000)  # 把1000換成None即為無限制,下面均是如此。
    pd.set_option('display.max_rows',500)
    pd.set_option('display.max_columns',500)
    pd.set_option('display.width',1000)
    

    上面的設置完之后會對后面的代碼全部做這個配置處理,如果想在代碼中動態的改變,還可以這么寫:

    with pd.option_context('display.max_rows', None, 'display.max_columns', None, 'display.width', None):
        logging.info('輸出打印DataFrame:\n{}'.format(data_frame))
    

    這樣在需要長顯示的時候套上with就可以了,不需要的地方繼續使用pandas的默認設置。

pandas的通用功能(官鏈)

pandas提供了很多general function來支持很多數據操作。比如上面提到過的pandas.melt還有其他經常用到的pandas.concat, pandas.merge, pandas.unique等,下面會介紹一些其他常用的功能:

  • pd.cut
    我們有時會需要把連續數值轉換為類別,比如根據取值的大小按照某種分隔標準來劃分成類別。
    更明確些,我們可能有兩種劃分依據,在pandas中均能找到對應的函數:1、按照取值來劃分,比如某個特征取值從0到1,我們希望按照這個取值范圍分成3等份,那么就可以用pd.cut;2、按照統計的個數來劃分,比如根據樣本在這個特征上的取值所統計的個數,分為好中差三個等樣本個數的分類,這時可以用pd.qcut;
    下面簡單介紹下幾個常用參數
    pd.cut(x=連續取值的數據, bins=整數N(會自動按照上下限的取值份N等份)/數組(會按照數組指示的間隔來劃分), labels=劃分后的標記)
    比如X的取值是0到1,希望按照(0, 0.25](0.25, 0.5](0.5, 0.75](0.75, 1]劃分成4份,且對應的label分別是1到4:
    pd.cut(X, bins=[i*1.0/4 for i in range(0, 4+1)], labels=range(1,4+1))

  • pd.qcut
    介紹幾個常用的參數
    pd.cut(x=連續取值的數據, q=整數N(會自動按照統計分位數分N等份)/數組(會按照數組指示的間隔來劃分), labels=劃分后的標記)
    比如q = [0, .25, .5, .75, 1.] for quartiles
    pd.qcut(range(5), 3, labels=["good", "medium", "bad"])

    ... 
    [good, good, medium, bad, bad]
    Categories (3, object): [good < medium < bad]
    
  • pd.get_dummies
    這個是對類別特征做one-hot編碼,比如pd.get_dummies(df, columns=df.columns)
    但是有個點需要注意下,比如現在有訓練集和測試集,其中訓練集中可能某個類別沒有在測試集中出現,或者測試集中的某個類別沒有在訓練集中出現。此時如果分別對它們做get_dummies就會出現得到的數據集的列對不起來。
    此時需要做的是,保證訓練集中的列一定都會出現,對于測試集中沒有包含訓練集的列添加并值為0,對于測試集中含有訓練集中沒有的去除,并保證兩個數據集的列順序一致。

df_train_onehot = pd.get_dummies(train_df, columns=train_df.columns)
train_oh_cols = df_train_onehot.columns
df_test_onehot = pd.get_dummies(test_df, columns=test_df.columns)
test_oh_cols = df_test_onehot.columns
miss_cols = set(train_oh_cols) - set(test_oh_cols)
for col in miss_cols:
    df_test_onehot[col] = 0
df_test_onehot = df_test_onehot[train_oh_cols]

除了上面這個做法外,還可以利用sklearn的OneHotEncoder來實現。
ohe = OneHotEncoder(sparse=False, handle_unknown='ignore')
然后在ohe.fit_transform(train_df)接著ohe.transform(test_df)即可,不過ohe返回的值都是np.ndarray類型,如果需要則自己命名列的名字。
第一種方法要保存的是訓練集的列名,第二種方法則要把fit后的ohe模型保留下來。

Matplotlib

常用作圖方法

import matplotlib.pyplot as plt
%matplotlib inline  # 在ipynb上顯示圖片

plt.plot([4, 3, 2, 1])  # 作圖代碼
plt.show()  # 在python運行程序時顯示

# 啟動ipython作圖時可以: ipython --pylab,這樣就會自動import matplotlib.pyplot as plt而且不用show()就可以輸出圖表。
plt.plot([4, 3, 2, 1])  # 使用ipython --pylab后直接顯示圖圖表

直接用數據作圖

  • 對于numpy的數組數據作圖:
fig = plt.figure()
ax1 = fig.add_subplot(2, 2, 1)
ax2 = fig.add_subplot(2, 2, 2)
ax3 = fig.add_subplot(2, 2, 3)
plt.plot([1.5, 3.5, -2, 1.6])  # 默認對最后創建的subplot作圖
import numpy as np
from numpy.random import randn
_ = ax1.hist(randn(100), bins=20, color='k', alpha=0.3)  # 直方圖
ax2.scatter(np.arange(30), np.arange(30) + 3 * randn(30))  # 散列圖
默認畫圖,直方圖和散列圖
  • 強調數據點
plt.plot(randn(30).cumsum(), 'ko--')  # 等價于下面語句
plt.plot(randn(30).cumsum(), color='k', linestyle='dashed', marker='o')
強調數據點位置
  • 圖中坐標和標題設置
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.plot(randn(1000).cumsum())
ticks = ax.set_xticks([0, 250, 500, 750, 1000])  # 設置X軸的刻度
labels = ax.set_xticklabels(['one', 'two', 'three', 'four', 'five'], rotation=30, fontsize='small')  # 刻度的標簽
ax.set_title('My first matplotlib plot')  # 圖的標題
ax.set_xlabel('Stages')  # X軸的名稱
設置坐標軸的信息和圖標題
  • 添加圖例
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.plot(randn(100).cumsum(), 'k', label='one')  # 創建圖例
ax.plot(randn(100).cumsum(), 'g--', label='two')
ax.plot(randn(100).cumsum(), 'r.', label='three')
ax.legend(loc='best')  # 把上面設置的圖例(legend)創建生效
圖例
  • 保存圖表到文件
plt.savefig('figpath.svg')
plt.savefig('figpath.png', dpi=400, bbox_inches='tight')

Pandas的繪圖函數

  • Series做柱狀圖
import pandas as pd
from pandas import Series, DataFrame
fig, axes = plt.subplots(nrows=2, ncols=1)  # 獲得subplot集合
data = Series(np.random.rand(16), index=list('abcdefghijklmnop'))
data.plot(kind='bar', ax=axes[0], color='k', alpha=0.7)  # 豎向柱狀圖,不設置kind默認是線形圖
data.plot(kind='barh', ax=axes[1], color='k', alpha=0.7)  # 橫向柱狀圖
Series柱狀圖
  • DataFrame做柱狀圖
df = DataFrame(np.random.rand(6, 4),
              index=['one', 'two', 'three', 'four', 'five', 'six'],
              columns=pd.Index(['A', 'B', 'C', 'D'], name='Genus'))
print(df)
df.plot(kind='bar')

df數據打印:
Genus A B C D
one 0.017426 0.964258 0.479931 0.636357

two 0.020693 0.979753 0.846889 0.436802
three 0.650068 0.608675 0.964375 0.866141
four 0.523848 0.610598 0.296204 0.879183
five 0.419329 0.023081 0.442044 0.842727
six 0.926948 0.454734 0.436056 0.970364

DataFrame的柱狀圖
  • 直方圖和密度圖
comp1 = np.random.normal(0, 1, size=200)  # N(0, 1)
comp2 = np.random.normal(10, 2, size=200) # N(10, 4)
values = Series(np.concatenate([comp1, comp2]))  # 合并為一個Series
values.hist(bins=100, alpha=0.3, color = 'k', normed=True)  # 直方圖
values.plot(kind='kde', style='k--')  # 密度圖(kde表示標準混合正態分布)
直方圖和密度圖
  • 散布圖
plt.scatter(trans_data['m1'], trans_data['unemp'])  # 散布圖
plt.title('Changes in log %s vs. log %s' % ('m1', 'unemp'))
散布圖
pd.plotting.scatter_matrix(trans_data, diagonal='kde', color='k', alpha=0.3)  # 散布圖矩陣
散布圖矩陣
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,363評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,497評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,305評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,962評論 1 311
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,727評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,193評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,257評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,411評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,945評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,777評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,978評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,519評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,216評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,657評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,960評論 2 373

推薦閱讀更多精彩內容