Pandas

# -*- coding:UTF-8 -*-
__autor__ = 'zhouli'
__date__ = '2019/2/13 21:38'


import pandas as pd
firsts = pd.DataFrame(
    {
        'val1': 1.0,
        'val2': [1, 2, 3, 4],
        'val3': ["test", "trains", "tony", "stark"],
        'val4': 'iron_man'
    }
)
print(firsts)

>>>
   val1  val2    val3      val4
0   1.0     1    test  iron_man
1   1.0     2  trains  iron_man
2   1.0     3    tony  iron_man
3   1.0     4   stark  iron_man

能夠看到的是正則表達式

①pandas會自動幫咱們作好了填充,很是方便,可是這也是一個容易出錯的點sql

②默認會生成默認索引數據庫

③這種方式是以列的形式賦值數組

 

 

pandas的數據結構:數據結構

Pandas的基本數據結構是Series和DataFrame,顧名思義,Series就是序列,相似一維數組app

DataFrame則是至關一張二維表格,相似二維數組,他的每個列都是一個Series。爲了定位Series中的元素,pandas提供了index對象,每個Series都會帶一個對應的index,用於標記不一樣的元素,index的內容不必定是數字,能夠是字母,中文等,相似SQL的主鍵。函數

相似的DataFrame至關於多個帶有一樣index的series的組合(本質是series的容器),每一個Series都帶有惟一的表頭,用來標識不一樣的Series編碼

pd.Series([1,2,3,4])
pd.Series([1,2,3,4], index=['a', 'b', 'c', 'd'])
pd.Series({'a':1, 'b':2})

Series是將list和dict結合在一塊兒的新數據類型,spa

就至關於把array多增長了一個標籤索引3d

st=pd.Series([1,2,3,4], index=['a', 'b', 'c', 'd'])
st[['a', 'b']]  # 花式索引
st['a']  # 標籤索引
st[0]  # 下標索引

這樣作的好處是什麼定位到一個表格中將列名做爲標籤索引

另外Series默認是標籤索引!

舉個栗子:

sr = pd.Series(np.arange(20))
sr2 = sr[10:].copy()

sr是什麼?

sr2是什麼?

那麼sr2[10]結果爲10

由於[]內默認是按照標籤索引來解釋,那若是就想用默認的索引怎麼辦?

sr2.iloc[]表明使用下標(當有衝突的時候)

sr2.loc[]表明使用標籤

 

Series---數據對齊

sr1 = pd.Series([12, 23, 34], index=['c', 'a', 'd'])
sr2 = pd.Series([11, 20, 10], index=['d', 'c', 'a'])
sr1 + sr2

這種狀況的index必須是一致的若是有不相同的部分就會出現NaN

那若是不想變成NaN咋辦呢?

sr1 = pd.Series([12, 23, 34], index=['c', 'a', 'd'])
sr2 = pd.Series([11, 20, 10], index=['b', 'c', 'a'])

 也就是如何讓在索引‘b’處的值爲11,在索引‘d’處的值爲34呢?

那就是使用pandas提供的算術方法:sub,add,div, mul

好比上面的例子:sr1.add(sr2, fill_value=0)若是不加fill_value仍是同樣的,fill_value是將不存在的賦值爲0

 

 

Series---缺失值的處理

 能夠先經過isnull()方法來判斷是否是NaN

與此相反的是還有notnull()方法

sr.notnull()

固然再用花式索引就能夠過濾出非缺失值

sr[sr.notnull()]

更加直接的是可使用sr.dropna()

同樣能夠過濾掉缺失值

那若是不去掉缺失值sr.fillna(0)

 將缺失值賦值爲0

可是若是是趨勢圖,賦值爲0就會不連續,所以通常取平均值就能夠表達爲sr.fillna(sr.mean())

在pandas中sr.mean()默認會跳過NaN取平均值

 

Series小結:

① 是數組字典的結合體(支持下標和標籤索引)

② 整數索引loc和iloc(解釋爲下標仍是標籤)

③ 數據對齊(不對齊出現NaN)

④ 確實數據的處理:

    1,扔掉dropna(),或者dropna(subset=['列名'])

    2,賦值fillna()

 

 

 

DataFrame()

 見下方例子:

那麼如何按照行的形式來創建數據呢?

pd.DataFrame(
    data=None,  # 數據列表,字典格式時直接同事提供變量名
    columns=None  # 變量名列表
)
import pandas as pd

data = [
    [1, "test"], [2, "trains"], [3, "tony"], [4, "stark"],
    ]
colums = ["val1", "val2"]
rows = pd.DataFrame(
    data=data,  # 數據列表,字典格式時直接同事提供變量名
    columns=colums  # 變量名列表
)
print(rows)
>>>
   val1    val2
0     1    test
1     2  trains
2     3    tony
3     4   stark

 

結合起來Series

pd.DataFrame({"one": pd.Series([1, 2, 3], index=['a', 'b', 'c']), "two": pd.Series([1, 2, 3, 4], index=['b', 'a', 'c', 'd'])})

DataFrame的經常使用屬性

① index 獲取行索引

② T 轉置(行列交換)

③ colums 獲取列索引

④ values 獲取值數組

⑤ describe() 獲取快速統計

DataFrame的切片和取值

df.loc[‘a, ‘one’]  默認是先是行後是列

不要使用df['one']['a']這種方式

 那若是須要切一行那就是df.loc['a',:] ,意思爲行是a,列是所有;等同於df.loc['a',]

 

缺失值的處理:

df.dropna()

①若是僅刪除一行全是NaN的數據的時候傳遞參數df.dropna(how='all')

 

 

DataFrame的去重:

在大多數的時間,數據中會存在大量重複的數據,在作分析以前須要進行去重:

data = pd.DataFrame({'k1': ['one']*3+['two']*4, 'k2': [3,2,1,3,3,4,4]})

使用data.drop_duplicates()

能夠看到,他在默認的狀況下會將徹底相同的行進行去重

當加上參數以後,subset表明的是當此值重複,pandas就認爲是重複的,keep是決定保留哪個,通常在使用keep的時候先用sort_values進行排序

若是須要查看重複的行

data[data.duplicated()]  # 查看重複的行

 

刪除已有的列:

datas = pd.read_excel(r'C:\Users\lenovo\Desktop\高校信息.xlsx', encodinh='gbk')
datas.drop(['名次', '類型'], axis=1)

固然後面寫的axis=1或者axis='columns'都是指按照列來處理

 

 

對列進行重命名:

datas.rename(columns={'學校名稱': '大學名稱','總分': '大學總分'})

 

 

pandas的分組技術:

說不清楚,直接看圖吧

 

 

datas = pd.read_excel(r'C:\Users\lenovo\Desktop\高校信息.xlsx', encodinh='gbk')
data = datas[['名次', '類型', '學校名稱', '所在城市', '所在省份']]
data.head()

比方計算各省的高校數量:

data[['學校名稱']].groupby(data['所在省份']).count()

再好比,計算各高校所在城市的數量,而且從高到低排序前十名:

data[['學校名稱']].groupby(data['所在城市']).count().sort_values('學校名稱', ascending=False).head(10)

那若是想要知道各個省份大學名次之和呢?

data[['名次']].groupby(data['所在省份']).sum().sort_values('名次', ascending=False).tail(10)

固然咱們仍是可使用自定義的函數進行聚合,首先須要自定義一個函數

def t_ranges(arr):
    return arr.max()-arr.min()
data[['名次']].groupby(data['所在省份']).agg(t_ranges).sort_values('名次', ascending=False).head(10)

注意,這裏使用了agg()函數,agg函數還指出傳入多個函數

data[['名次']].groupby(data['所在省份']).agg(['sum', 'mean','max',t_ranges]).tail(10)  # 在這裏,agg裏面傳入列表,可是須要傳入str字符串

在agg()函數中不只能夠應用同一種函數,還能夠經過不一樣的列應用不一樣的求解函數,下面須要分別對名次和類型應用不一樣的統計函數,並輸出不一樣列的數據,

這是能夠經過agg自定義函數實現,只須要傳入以列名爲鍵值得字典

data[['名次', '類型']].groupby(data['所在省份']).agg({'名次': [t_ranges],'類型':['count']}).head()

agg()函數返回的不是DataFrame格式的,使用apply()函數

data.groupby(data['所在省份']).apply(lambda x: x[:3]).head(9)  # 在這裏傳入一個匿名函數,返回按照省份的前三個高校的信息

 

 

pandas的pivot_table(index="XXX", values=["ss", "dd"].aggfunc=np.sum)

index表明統計的數據是以XXX爲基礎的

values表明統計的數據和XXX之間的關係

aggfunc表明上述兩個量之間的關係

 

pandas的經常使用函數:

①mean()方法

這個方法是用於求平均值df.mean()會自動忽略NaN

若是是行求平均值的話只須要加上一個參數df.mean(axis=1)便可

②sum()方法(同理上面)

③排序sort_values(by='two')  參數ascending=False倒序排列;若是是多列排序的話by能夠傳入列表(後面若是加上參數inplace=True,就表明用排好序的數據覆蓋原始數據)

④按照索引排列sort_index(axis,……ascending)

Numpy的通用函數一樣適合pandas

 

 

pandas的時間對象處理

pd.to_datetime(['2001-01-01', '2010/Feb/02'])
>>>
DatetimeIndex(['2001-01-01', '2010-02-02'],dtype='datetime64[ns]', freq=None)

to_datetime是能夠傳入數組或者是列表,批量處理時間

pd.date_range()

參數start是開始時間,end爲結束時間;若是不指定end,那麼periods就是表明長度

freq表示頻率,這個就是控制periods,‘H’是小時,‘W’是周,‘W-MON’表明每週一,‘B’表明工做日

就是去除週六周天工做日,‘SM’表明半個月,‘T’是分鐘,‘S’是秒,‘A’是年;

更離譜的是freq能夠寫成1h20min

pd.date_range('2010-01-03', periods=60, freq='1h20min')

 

 

時間序列:

咱們能夠看到date_range產生的是DatetimeIndex,也就是能夠說當作series的索引

sr = pd.Series(np.arange(100), index=pd.date_range('2019-01-01',periods=100))

可是能夠看到的是索引貌似是字符串,可是咱們使用index方法看一下sr.index

他成爲一個時間序列了,那有什麼好處呢?

①我想查找全部2019年3月的數據

sr['2019-03']

 

若是僅僅看年就是sr['2019']

sr['2001':'2019-03-08'] 都是能夠的

也能夠按照周啊,天啊進行重列查看狀況

sr.resample('M').sum()

 

文件的讀取:

利用pandas讀入文本格式數據文件

import pandas as pd

pd.read_csv(
    filepath_or_buffer='',  # 要讀入文件的路徑
    sep=',',  # 列分隔符,也能夠傳遞正則表達式
    header='infer',  # 指定數據中第幾行做爲變量名,若是是None就是自動生成列名
    names=None,  # 自定義變量名列表, 
    index_col=None,  # 將會被用做索引的列名,多列時只能使用序號列表
    usecols=None,  # 指定只讀入某些列,使用索引列表或名稱列表都可
    # (0, 1, 3), ["名次", "學校名稱", ""]
    encoding=None,  # 讀入文件的編碼方式
    na_values='',  # 指定將被讀入爲缺失值的數值列表,默認下列數據被讀入,好比表格中None就讀爲NaN
    '''
    '','#N/A','#N/A N/A', '#NA', 'NULL'等
    '''
parse_dates=True, # 將表中能解釋爲時間序列的列解釋爲時間序列,也能夠傳遞列名
) pd.read_table() # 更加通用的文本讀取命令

讀取CSV格式的文件,也是能夠通用於文本文件的讀取

那這兩個方法有什麼讀取文本的命令基本上一致,最大的區別的地方在於sep

read_csv是',',而另外一個是sep='\t',即tab符號

舉個栗子:

這個是中國高校排行榜

high_school = pd.read_csv("high_school.csv", encoding='gbk')
print(high_school)

結果以下:

 

若是不適用read_csv,而是採用read_rable

結果就是這樣

可是注意的是,table是按照\t來的,因此read_table的讀取方式是整行讀取,因此沒有分割

 

數據的導入與導出:

1,Excel文件的讀入:

high_school = pd.read_excel("high_school1.xlsx", sheet_name="full")
print(high_school, high_school.describe()  # 查看數據的基本狀況)

sheet_name寫full或者不寫都是同樣的,由於默認都是讀取第一個sheet

當sheet_name寫0的時候也是至關於讀取第一個sheet

 

 

讀入統計軟件數據集:

例如讀SAS/Stata:

pd.read_sas()

pd.read_stata()

 

 

讀入數據庫的文件:

①讀入數據表

pd.read_sql

pd.read_sql(
    sql='',  # 須要執行的sql語句/要讀入的表名名稱
    con='',  # SQLAlchemy鏈接引擎名稱
    index_col=None, # 將被用做索引的列名稱
    columns=None,  # 將提供表名稱時,須要讀入的列名稱list
)
pd.read_sql(
    sql='basic',  # 表名爲basic
    con=eng,  # SQLAlchemy鏈接引擎名稱eng
)

數據的導出:

to_csv

參數有:

① sep  指定文件分隔符

② na_rep 指定缺失值轉換的字符串,默認爲‘’

③ header=False 不輸出列名一行

④ index=False 不輸出行索引一列

⑤ cols 指定輸出的列,傳入列表

 

 

pandas和matplotlib

df.plot()

plt.show()

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息