Pandas之二維數組DataFrame

DataFrame是一個多維數據類型。由於一般使用二維數據,所以,咱們能夠將DataFrame理解成相似excel的表格型數據,由多列組成,每一個列的類型能夠不一樣。Series其實就是一列數組

由於DataFrame是多維數據類型,所以,DataFrame既有行索引,也有列索引。bash

DataFrame建立方式

咱們可使用以下的方式建立(初始化)DataFrame類型的對象(經常使用):數據結構

  • 二維數組結構(列表,ndarray數組,DataFrame等)類型。
  • 字典類型,key爲列名,value爲一維數組結構(列表,ndarray數組,Series等)。

說明:app

  • 若是沒有顯式指定行與列索引,則會自動生成以0開始的整數值索引。咱們能夠在建立DataFrame對象時,經過index與columns參數指定。
  • 能夠經過head,tail訪問前 / 後N行記錄(數據)。

# 使用二維數據結構建立DataFrame。沒有指定行列索引,自動生成行列索引。都是從0開始的天然數
array1 = np.random.rand(3, 5)
df = pd.DataFrame(array1)
print(df)

# 錯誤,超過了2d。
# df_more_than2d = pd.DataFrame(np.random.rand(3, 3, 3))
          0         1         2         3         4
0  0.877072  0.941101  0.131574  0.056032  0.141660
1  0.129488  0.211658  0.786556  0.477778  0.912969
2  0.624839  0.336306  0.936274  0.581543  0.541653複製代碼

# 使用字典來建立DataFrame。一個鍵值對爲一列。key指定列索引,value指定該列的值。
df = pd.DataFrame({"北京":[100, 200, 125, 112], "天津":[109, 203, 123, 112], "上海":[39, 90, 300, 112]})
display(df)
複製代碼


# 顯示前N條記錄
display(df.head(2))
# 顯示後N條記錄
display(df.tail(2))
# 隨機抽取N條記錄
display(df.sample(2)) 複製代碼


# 建立DataFrame,指定行,列索引。
df = pd.DataFrame(np.random.rand(3, 5), index=["地區1", "地區2", "地區3"], columns=["北京","天津", "上海","瀋陽", "廣州"])
display(df)複製代碼


DataFrame相關屬性

  • index 索引
  • columns 列
  • values 值
  • shape 形狀
  • ndim 維度
  • dtypes 數據類型

說明:dom

  • 能夠經過index訪問行索引,columns訪問列索引,values訪問數據,其中index與columns也能夠進行設置(修改)。
  • 能夠爲DataFrame的index與columns屬性指定name屬性值。
  • DataFrame的數據不能超過二維。

df = pd.DataFrame(np.random.rand(3, 5), index=["地區1", "地區2", "地區3"], columns=["北京","天津", "上海","瀋陽", "廣州"])
# 查看idnex, columns, values等屬性
display(df.values, type(df.values))  # 返回DataFrame關聯的ndarray數組
display(df.index)   # 返回行索引
display(df.columns)  # 返回列索引
array([[0.88915553, 0.09234275, 0.41773469, 0.92490647, 0.13286735],
       [0.85550017, 0.06293159, 0.75023895, 0.01887861, 0.327761  ],
       [0.13309605, 0.98347602, 0.95935583, 0.92139592, 0.48752687]])numpy.ndarrayIndex(['地區1', '地區2', '地區3'], dtype='object')Index(['北京', '天津', '上海', '瀋陽', '廣州'], dtype='object')複製代碼

# 返回形狀
display(df.shape)

# 返回維度
display(df.ndim)

# 返回各列的類型信息。
display(df.dtypes)
(3, 5)2北京    float64
天津    float64
上海    float64
瀋陽    float64
廣州    float64
dtype: object複製代碼

DataFrame相關操做

假設df爲DataFrame類型的對象。函數

列操做

  • 獲取列【哪一個更好些?】
    • df[列索引]
    • df.列索引
  • 增長(修改)列:df[列索引] = 列數據
  • 刪除列
    • del df[列索引]
    • df.pop(列索引)
    • df.drop(列索引或數組)

行操做

  • 獲取行
    • df.loc 根據標籤進行索引。
    • df.iloc 根據位置進行索引。
    • df.ix 混合索引。先根據標籤索引,若是沒有找到,則根據位置進行索引(前提是標籤不是數值類型)。【已不建議使用, 新版本廢棄】
  • 增長行:append【屢次使用append增長行會比鏈接計算量更大,可考慮使用pd.concat來代替】
  • 刪除行
    • df.drop(行索引或數組)

行列混合操做:

  • 先獲取行,再獲取列。
  • 先獲取列,在獲取行。

說明:ui

  • drop方法既能夠刪除行,也能夠刪除列,經過axis指定軸方向。【能夠原地修改,也能夠返回修改以後的結果。】
  • 經過df[索引]訪問是對列進行操做。
  • 經過df[切片]訪問是對行進行操做。【先按標籤,而後按索引訪問。若是標籤是數值類型,則僅會按標籤進行匹配。】
  • 經過布爾索引是對行進行操做。
  • 經過數組索引是對列進行操做。

這個地方重點區分,極易混淆。
換種方式進行總結:spa

  • 行操做:切片 和 布爾數組
  • 列操做:索引 和 標籤數組/位置數組

df = pd.DataFrame(np.random.rand(5, 5), columns=list("abcde"), index=list("hijkl"))
display(df)複製代碼


# 獲取多個列(返回一個DataFrame,即便只選擇一個列)
display(df[["a", "d"]])複製代碼


# 刪除列
df["e"] = [6, 7, 8, 9, 10]
del df["e"]
df["e"] = [6, 7, 8, 9, 10]     # 把e列加回去
display(df.pop("e"))           # 從df中刪除e列,會返回刪除的列e
display(df)
複製代碼


h     6
i     7
j     8
k     9
l    10
Name: e, dtype: int64複製代碼


df2 = df.drop("h", inplace=False, axis=0)
display(df, df2)複製代碼


# 先構造一個DataFrame
np.random.seed(100)
df = pd.DataFrame(np.random.rand(5, 5), index=list("abcde"), columns=list("yuiop"))
display(df)複製代碼


# 先獲取行,再獲取列, 其實loc是從高維到低維逐漸定位的。
display(df.loc["c"]["i"])
display(df.loc["c", "i"])
display(df.loc["c"].loc["i"])
display(df.loc["c"])    # loc函數是從高維到低維依次定位的。不能不指定高維,直接定位到低維
display(df.loc[:, "i"])
0.185328219550075060.185328219550075060.18532821955007506y    0.891322
u    0.209202
i    0.185328
o    0.108377
p    0.219697
Name: c, dtype: float64a    0.424518
b    0.825853
c    0.185328
d    0.171941
e    0.817649
Name: i, dtype: float64複製代碼

# 先獲取列,在獲取行。
df["i"].loc["a"] = 3
display(df)

# 標籤索引組定位列,而後loc切片行
display(df[["i", "o", "p"]].loc["b":"d"])複製代碼


# 若是布爾數組是二維結構,則True對應的位置元素原樣顯示,False對應位置的元素置爲空值(NaN)
display(df > 0.5)
display(df[df > 0.5])
display(df["i"] > 0.5)
display(df[df["i"] > 0.5])
複製代碼


df = pd.DataFrame(np.random.rand(5, 5), columns=list("abcde"), index=list("hijkl"))
display(df)
# DataFrame行操做
# 獲取行 loc iloc ix
# loc 根據標籤獲取
# iloc 根據位置獲取

# ix 混合索引 先根據標籤,而後再根據位置
display(df.loc["i"])
display(df.iloc[1])

# 不建議使用,由於很是容易形成混淆。
display(df.ix["i"])
display(df.ix[1])複製代碼


a    0.598843
b    0.603805
c    0.105148
d    0.381943
e    0.036476
Name: i, dtype: float64複製代碼
a    0.598843
b    0.603805
c    0.105148
d    0.381943
e    0.036476
Name: i, dtype: float64複製代碼
a    0.598843
b    0.603805
c    0.105148
d    0.381943
e    0.036476
Name: i, dtype: float64複製代碼
a    0.598843
b    0.603805
c    0.105148
d    0.381943
e    0.036476
Name: i, dtype: float64複製代碼

總結

1)選取某一整行(多個整行)或某一整列(多個整列)數據時,能夠用df[]、df.loc[]、df.iloc[],此時df[]的方法書寫要簡單一些。3d

2)進行區域選取時,若是隻能用標籤索引,則使用df.loc[]或df.ix[],若是隻能用整數索引,則用df.iloc[]或df.ix[]。不過我看到有資料說,不建議使用df.ix[],由於df.loc[]和df.iloc[]更精確(有嗎?我沒理解精確在哪,望告知)。excel

3)若是選取單元格,則df.at[]、df.iat[]、df.loc[]、df.iloc[]均可以,不過要注意參數。  

4)選取數據時,返回值存在如下狀況:

若是返回值包括單行多列或多行單列時,返回值爲Series對象; 若是返回值包括多行多列時,返回值爲DataFrame對象; 若是返回值僅爲一個單元格(單行單列)時,返回值爲基本數據類型,例如str,int等。

5)df[]的方式只能選取行和列數據,不能精確到單元格,因此df[]的返回值必定DataFrame或Series對象。

6)當使用DataFrame的默認索引(整數索引)時,整數索引即爲標籤索引。

DataFrame 增刪改

df = pd.DataFrame(np.random.rand(5, 5), columns=list("abcde"), index=list("hijkl"))
display(df)

# 增長一行
line = pd.Series([23, 33, 12., 334.22, 200], index=list("abcde"), name="p")
df = df.append(line)
display(df)

# 刪除一行
df1 = df.drop(["h", "j"])
display(df1)

# 修改一行
df.loc["k"] = pd.Series([1,1,1,1,1], index=list("abcde"))
display(df)複製代碼



DataFrame結構

DataFrame的一行或一列,都是Series類型的對象。
對於行來講,Series對象的name屬性值就是行索引名稱,其內部元素的值,就是對應的列索引名稱。
對於列來講,Series對象的name屬性值就是列索引名稱,其內部元素的值,就是對應的行索引名稱。

DataFrame運算

DataFrame的一行或一列都是Series類型的對象。所以,DataFrame能夠近似看作是多行或多列Series構成的,Series對象支持的不少操做,對於DataFrame對象也一樣適用,咱們能夠參考以前Series對象的操做。

  • 轉置
  • DataFrame進行運算時,會根據行索引與列索引進行對齊。當索引沒法匹配時,產生空值(NaN)。若是不想產生空值,可使用DataFrame提供的運算函數來代替運算符計算,經過fill_value參數來指定填充值。
  • DataFrame與Series混合運算。【默認Series索引匹配DataFrame的列索引,而後進行行廣播。能夠經過DataFrame對象的運算方法的axis參數,指定匹配方式(匹配行索引仍是列索引)。】

df1 = pd.DataFrame(np.arange(9).reshape(3, 3))
df2 = pd.DataFrame(np.arange(9, 18).reshape(3, 3))
display(df1, df2)
display(df1 + df2)
display(df1 * df2)複製代碼


索引排序

Series與DataFrame對象可使用sort_index方法對索引進行排序。DataFrame對象在排序時,還能夠經過axis參數來指定軸(行索引仍是列索引)。也能夠經過ascending參數指定升序仍是降序。

df = pd.DataFrame(np.random.random((3, 5)), index=[3,1,2], columns=[1,3,5,2,4])
display(df)複製代碼


# 指定按照行索引排序
display(df.sort_index(axis=0, ascending=False))複製代碼


# 指定按照列索引排序
display(df.sort_index(axis=1, ascending=True))複製代碼


df = pd.DataFrame(np.arange(9).reshape(3, 3), index=[3, 1, 2], columns=[6, 4, 5])
display(df)
# 默認根據行索引進行排升序。
df1 = df.sort_index()
display(df1)
# 根據列索引進行排序
df2 = df.sort_index(axis=1)
display(df2)
複製代碼

      

# 就地修改,不會返回修改後的結果。
df.sort_index(inplace=True)
display(df)
# 默認爲升序排序,能夠指定爲降序排序。
df3 = df.sort_index(ascending=False, axis=1)
display(df3)
複製代碼

   

值排序

Series與DataFrame對象可使用sort_values方法對值進行排序。

df = pd.DataFrame([[1,3, 2], [5, 2, 4], [2, 4, 3]], index=[1,3,2], columns=list("cab"))
display(df)

# 按照列排序,指定順序
df1 = df.sort_values("c", ascending=False)
display(df1)

# 按照行排序,指定順序
df2 = df.sort_values(1, axis=1, ascending=False)
display(df2)

# 值排序
df = pd.DataFrame([[1, 3, 300], [66, 5, 100], [1, 3, 400]])
display(df)

# 根據第2列排升序
df1 = df.sort_values(2)
display(df1)

# 根據第1行排降序
df2 = df.sort_values(1, axis=1, ascending=False)
display(df2)
複製代碼

DataFrame索引對象Index

Series(DataFrame)的index或者DataFrame的columns就是一個索引對象。

  • 索引對象能夠向數組那樣進行索引訪問。
  • 索引對象是不可修改的。

DataFrame統計相關方法

  • mean / sum / count
  • max / min
  • cumsum / cumprod
  • argmax / argmin
  • idxmax / idxmin
  • var / std
相關文章
相關標籤/搜索