數據分析(4)--Pandas+DataFrame

DataFrame類型

DataFrame是一個多維數據類型。因爲通常使用二維數據,因此,我們可以將DataFrame理解成類似excel的表格型數據,由多列組成,每個列的類型可以不同。
因爲DataFrame是多維數據類型,因此,DataFrame既有行索引,也有列索引。

創建方式

我們可以使用如下的方式創建(初始化)DataFrame類型的對象(常用):

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

說明:

  • 如果沒有顯式指定行與列索引,則會自動生成以0開始的整數值索引。我們可以在創建DataFrame對象時,通過index與columns參數指定。
  • 可以通過head,tail訪問前 / 後N行記錄(數據)。
df = pd.DataFrame({0:[1, 2, 3], 1:5})
# 創建DataFrame類型。
# 使用二維數組結構來創建。
# df = pd.DataFrame([[10, 20, 39], [43, 51, 62]])
# df2 = pd.DataFrame([[5, 3, 10], [11, 35, 86]])
# print(df)
# print(df)

# a = np.array([1, 2, 3, 4, 5])
# print(a)
# a

# display函數。
# display與print比較相似,都是在控制檯上輸出結構。不同的是,display在某些對象上,顯示的會比print
# 更加友好。使用display與我們直接求值輸出效果相同,但是,直接求值輸出僅會顯示最後一個求值的結果。
# 注意:display不是python的內建函數。是否IPython中擴展的函數。
# df
# df2
# display(df)
# display(df2)
# 一次輸出多個值。
# display(df, df2)

# 通過字典創建DataFrame類型的對象。字典中每個鍵值對爲DataFrame對象的一列。
# key就是我們的列標籤(列名或列索引),value爲該列對應的值。
# df = pd.DataFrame({0: [10, 42], 1: [20, 51], 2:[39, 62]})
# df = pd.DataFrame({"A": [10, 42], "B": [20, 51], "C":[39, 62]})
# display(df)

# 如果沒有顯式指定DataFrame的索引(行,列),則會創建從0開始,1爲增量的索引序列。
# 我們也可以通過index與columns屬性來自定義索引。index表示行索引,columns表示列索引。
# df = pd.DataFrame([[10, 20, 39], [43, 51, 62]], index=["a", "b"], columns=["c", "d", "e"])
df = pd.DataFrame(np.random.random(size=(100, 5)))
# 我們也可以使用head與tail方法來查看DataFrame對象的前(後)n條記錄。默認爲5。
# df.head()
# df.tail(3)

相關屬性

  • index
  • columns
  • values
  • shape
  • ndim
  • dtypes

說明:

  • 可以通過index訪問行索引,columns訪問列索引,values訪問數據,其中index與columns也可以進行設置(修改)。
  • 可以爲DataFrame的index與columns屬性指定name屬性值。
  • DataFrame的數據不能超過二維。
# index 表示行索引,columns表示列索引。
df = pd.DataFrame(np.random.random(size=(4, 5)))
# 我們也可以在創建DataFrame對象之後,再去修改index與columns屬性。
df.index = ["a", "b", "c", "d"]
df.columns = [10, 11, 12, 13, 14]
display(df)
# index與columns返回DataFrame的索引對象。
# type(df.index), type(df.columns)

# values 返回DataFrame的數據(二維數組類型)
# display(df.values)

# shape 返回數據的形狀。
# display(df.shape)
# 返回數據的維度。
# display(df.ndim)
# 返回數據的類型。(每列的數據類型。)
# display(df.dtypes)

# 我們可以爲index與columns指定name屬性。
# df.index.name = "行索引名稱"
# df.columns.name = "列索引名稱"
# display(df)

# DataFrame的數據維度不能超過二維
# a = np.random.random((3, 3, 3))
# df = pd.DataFrame(a)

DataFrame相關操作

假設df爲DataFrame類型的對象。

列操作

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

行操作

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

行列混合操作:

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

說明:

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

在對行或列進行操作時,如果針對多行(列)進行操作?如果是不連續的呢?

df = pd.DataFrame(np.random.random((5, 4)), columns=["a", 0, "c", "d"])
# display(df)
# 獲取列。通過df[標籤]永遠是獲取列。
# 獲取列,我們可以使用df["列名"],也可以使用df.列名。建議使用第一種方式。因爲第一種方式侷限性少,
# 當列名不是合法的標示符時,也能夠使用。
# display(df[0])
# 錯誤。
# display(df.0)

# 增加 / 修改列
# 增加與修改列的語法是相同的,如果列名(列索引)在DataFrame中存在,則修改該列,
# 如果不存在,則增加一列。
# df["e"] = [10, 20, 30, 40, 50]
# 也可以使用標量。
# df["e"] = 30
# df["a"] = [30, 40, 50, 60, 70]
# display(df)

# 刪除
# del df["a"]
# df.pop("a")
# display(df.drop("a", axis=1))
# df = df.drop("a", axis=1)
# df.drop("a", axis=1, inplace=True)
# display(df)
# display(df)
# 對DataFrame行進行的操作
df = pd.DataFrame(np.random.random((5, 3)), index=["a", "b", "c", "d", "e"])
display(df)
# 獲取行
# 根據標籤獲取一行。
# display(df.loc["b"])
# 根據位置獲取一行。
# display(df.iloc[1])
# 不建議使用ix來獲取行。因爲會帶來不必要的混淆。
# df = df.append(pd.Series([300, 200, 100], name="新增"))
# display(df)

# df2 = pd.DataFrame(np.random.random((3, 3)), index=["a", "b", "c"])
# 如果要增加一行(少量的行),可以使用append。如果是增加多行,建議使用concat。
# r = pd.concat([df, df2], axis=1)
# display(r)

# 刪除行
# df.drop("a", axis=0, inplace=True)
# 刪除多行(列)
# df.drop(["a", "c"])
# df.drop([0, 2], axis=1)

# 行列混合操作
# 先獲取行,再獲取列。
# df.loc["a"].loc[1]
# 先獲取列,再獲取行。
# df[2].loc["a"]

# 混淆之處
# df[索引] 獲取列
# df[切片] 獲取行
# 因此,如果需要對行進行切片,建議df.loc[切片]或df.iloc[切片]

# 既然df[切片]是獲取行,那如果要獲取多個列呢?
# df[ [] ]  通過數組進行索引提取元素,是對列進行操作。
# df[[0, 1]]
# df.iloc[:, :-1]

# 通過布爾類型數組提取元素,是對行進行的操作。
# 如果布爾類型的數組是一維結構,則值爲True,提取對應位置的該行,否則丟棄該行。
# b = [True, True, False, False, False]
# df[b]
# 如果布爾類型的數組是二維結構,如果值爲True,則保留對應位置的元素,否則,將對應位置的元素置爲NaN。(空值)
df[df > 0.5]
# 當我們選擇(截取)DataFrame的時候。如果我們單純選擇一行(列),返回的是Series類型。
df = pd.DataFrame(np.random.random((5, 3)), columns=["a", "b", "c"], index=["r1", "r2", "r3", "r4", "r5"])
# type(df["a"])
# type(df.iloc[0])
# 當我們使用切片選擇多行多列的時候,返回DataFrame類型。
# type(df.iloc[0:2, 0:2])
# 多行一列,或一行多列,返回Series類型。
# type(df.iloc[1, 0:2])
# type(df.iloc[0:2, 0])
# 如果使用切片,即使截取出的結果是單行(單列),返回的類型,依然是DataFrame類型。
# type(df.iloc[1:2, 0:2])

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參數,指定匹配方式(匹配行索引還是列索引)。】
df = pd.DataFrame(np.arange(16).reshape(4, 4))
df2 = pd.DataFrame(np.arange(16, 32).reshape(4, 4), columns=[1, 2, 3, 4])
# display(df, df2)
# 轉置
# display(df.T)
# 會根據行索引與列索引對齊,無法匹配,則產生NaN。
# display(df + df2)
# 可以使用DataFrame提供的運算方法,代替運算符。這樣可以填充空值。
# df.add(df2, fill_value=0)
s = pd.Series([100, 200, 300, 400])
# DataFrame與Series進行混合運算,Series會匹配DataFrame的列索引。
# df + s
# 如果希望Series能夠匹配DataFrame的行索引,我們可以通過函數計算,同時將axis的值設置爲0或index。
df.add(s, axis=0)

排序

索引排序

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

值排序

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

# 對索引進行排序
df = pd.DataFrame(np.arange(9).reshape(3, 3), index=["c", "a", "b"], columns=["y", "k", "x"])
# 默認對行索引,升序排列
# df.sort_index()
# 可以通過axis參數來指定對行(列)排序。
# df.sort_index(axis=1)
# 我們可以指定ascending來控制是升序排列還是降序排列,默認是升序排列。
# df.sort_index(ascending=False)

# 對值進行排序。
# df.sort_values("c", axis=1)
# df.sort_values("y", ascending=False)

# 對索引或對值進行排序時,可以指定inplace=True,進行就地修改。

索引對象

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

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

統計相關方法

  • mean / sum / count
  • max / min
  • cumsum / cumprod
  • argmax / argmin
  • idxmax / idxmin
  • var / std
  • corr / cov
df = pd.DataFrame([[8, 3, 4], [1, 2, 10]])
display(df)
df.idxmax(axis=1)

在這裏插入圖片描述

其他

  • unique
  • value_counts
# s = pd.Series([1, 5, 4, 1, 5])
# 去掉重複的值。(無排序的功能)
# s.unique()

df = pd.DataFrame(np.random.randint(1, 10, size=(100, 3)))
df[2].value_counts(sort=True, ascending=True)

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章