高手系列!資料科學傢俬藏pandas高階用法大全 ⛵

ShowMeAI發表於2022-12-01
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵

? 作者:韓信子@ShowMeAI
? 資料分析實戰系列https://www.showmeai.tech/tutorials/40
? 本文地址https://www.showmeai.tech/article-detail/394
? 宣告:版權所有,轉載請聯絡平臺與作者並註明出處
? 收藏ShowMeAI檢視更多精彩內容

如果你是資料科學家、資料分析師、機器學習工程師,或者任何 python 資料從業者,你一定會高頻使用 pandas 這個工具庫——它操作簡單功能強大,可以很方便完成資料處理、資料分析、資料變換等過程,優雅且便捷。

? Python資料分析實戰教程

高手系列!資料科學傢俬藏pandas高階用法大全 ⛵

在本文中,ShowMeAI給大家彙總介紹 21 個 Pandas 的提示和技巧,熟練掌握它們,可以讓我們的程式碼保持整潔高效。

? 1:DataFrame.copy()

如果我們希望對DataFrame操作,但是不希望改變原始DataFrame,我們可以使用df.copy()製作副本,如下例所示:

import pandas as pd

df = pd.DataFrame({"col1": [1, 2, 3],
                   "col2": [4, 5, 6]})

df2 = df # Make a copy using =
df2["col1"] = [7, 8, 9]
df # df also changes
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵
# Recrate df
df = pd.DataFrame({"col1": [1, 2, 3],
                   "col2": [4, 5, 6]})

df3 = df.copy() # Create a copy of df
df3["col1"] = [7, 8, 9]
df # df doesn't change
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵

? 2:Groupby().count 與 Groupby().size

如果你想獲得 Pandas 的一列的計數統計,可以使用groupbycount組合,如果要獲取2列或更多列組成的分組的計數,可以使用groupbysize組合。如下所示:

import pandas as pd

df = pd.DataFrame(
    {
        "col1": ["a", "b", "b", "c", "c", "d"],
        "col2": ["S", "S", "M", "L", "L", "L"]
    }
)

# get the count of elements in one column
df.groupby(["col1"]).count()
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵
# Get the size of groups of 2+ columns
df.groupby(["col1", "col2"]).size()
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵

? 3:歸一化值計數

大家都知道,我們可以使用value_counts獲取列裡的取值計數,但是,如果要獲取列中某個值的百分比,我們可以新增normalize=Truevalue_counts引數設定來完成:

import pandas as pd

size = pd.Series(["S", "S", "M", "L", "S", "XL", "S", "M",])

# Get count of each value
size.value_counts()
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵
# Get percentage of each value
size.value_counts(normalize=True)
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵

? 4:值計數(包含缺失值)

我們知道可以透過value_counts很方便進行欄位取值計數,但是pandas.value_counts()自動忽略缺失值,如果要對缺失值進行計數,要設定引數dropna=False

import pandas as pd

size = pd.Series(["S", "S", None, "M", "L", "S", None, "XL", "S", "M",])

# Get count of each value, it does not count missing values
size.value_counts()
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵
# pass dropna=False to get missing value count
size.value_counts(dropna=False)
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵

? 5:df.transform() 與 df.count()

如下例所示,如果我們要對列的取值統計並進行計數過濾,使用count會報錯,使用transform是恰當的方法,如下例所示:

import pandas as pd

df = pd.DataFrame({
    "type": ["A", "A", "O", "B", "O", "A"],
    "value": [5, 3, 2, 1, 7, 3]
})

# Using count will throw an error because the
# Series returned is shorter than the original
# DataFrame

# df.loc[df.groupby("type")["type"].count() > 1]
df.loc[df.groupby("type")["type"].transform("size") > 1]
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵

? 6:列印Markdown表格

Markdown 是一種輕量級標記語言,用於使用純文字編輯器建立格式化文字。我們有時候會想在 markdown 格式中列印一個DataFrame,這時可以使用to_markdown()功能:

import pandas as pd

df = pd.DataFrame({'a': [1, 2, 3, 4],
                   'b': [5, 6, 7, 8]})

# You can control the printing of the index column
# by using the flag index.
print(df.to_markdown(index=True))
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵
# Ouput markdown with a tabulate option
print(df.to_markdown(tablefmt="grid", index=True))
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵
# To create a markdown file from the dataframe, pass
# the file name as paramters
df.to_markdown("README.md", tablefmt="grid", index=True)
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵

? 7:將分組後欄位聚合為列表

我們經常會使用groupby對資料進行分組並統計每組的聚合統計資訊,例如計數、平均值、中位數等。如果您想將分組後的資料欄位整合成列表,可以使用lambda x:list(x),如下示例:

import pandas as pd

df = pd.DataFrame(
    {
        "col1": [1, 2, 3, 4, 3],
        "col2": ["a", "a", "b", "b", "c"],
        "col3": ["d", "e", "f", "g", "h"],
    }
)

# Group by col2
df.groupby(["col2"]).agg(
    {
        "col1": "mean",           # get mean
        "col3": lambda x: list(x) # get list
    }
)
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵

? 8:DataFrame.explode()

類似於上例,如果你想把一個DataFrame中某個字串欄位(列)展開為一個列表,然後將列表中的元素拆分成多行,可以使用str.split()explode()組合,如下例:

import pandas as pd


df = pd.DataFrame({"a": ["1,2", "4,5"],
                   "b": [11, 13]})


# Turn strings into lists
df.a = df.a.str.split(",")
df
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵
print(df.explode("a", ignore_index=False))
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵

? 9:資料相關性

如果要計算兩個 DataFrame 的行或列之間的相關性,可以使用.corrwith()

import pandas as pd

df1 = pd.DataFrame({
    "a": [1, 2, 3, 4],
    "b": [2, 3, 4, 6]
})

df2 = pd.DataFrame({
    "a": [1, 2, 3, 3],
    "b": [2, 2, 5, 4]
})

df1.corrwith(df2)
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵

? 10:交叉製表

交叉製表支援我們分析多個變數之間的關係,可以使用pandas.crosstab()功能:

import pandas as pd

network = [
    ("Ben", "Smith"),
    ("Ben", "Patrick"),
    ("Warren", "Jone"),
    ("Warren", "Smith"),
    ("Smith", "Patrick"),
]

# Create a dataframe of the network
friends1 = pd.DataFrame(
    network, columns=["person1", "person2"]
)

# Create the order of the columns
friends2 = pd.DataFrame(
    network, columns=["person2", "person1"]
)

# Create a symmetric dataframe
friends = pd.concat([friends1, friends2])

# Create a cross tabulation
pd.crosstab(friends.person1, friends.person2)
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵

? 11:DataFrame.query()

我們可以使用df.query()功能進行資料過濾,它支援以簡潔的方式疊加很多個條件。

import pandas as pd

df = pd.DataFrame({
    "fruit": ["apple", "orange", "grape", "grape"],
    "price": [4, 5, 6, 7]
})

# Filter using brackets
df[(df.price > 4) & (df.fruit == "grape")]
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵
# Filter using query
df.query("price > 4 & fruit == 'grape'")
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵

? 12:逆透視資料表

如果要將 DataFrame 從寬表格式轉換為長表格式,可以使用pandas.melt()

  • 如下例,我們可以使用pandas.melt()將多列(“Aldi”、“Walmart”、“Costco”)轉換為一列(“store”)的值。
import pandas as pd

df = pd.DataFrame({
    "fruit": ["apple", "orange"],
    "Aldi": [4, 5],
    "Walmart": [6, 7],
    "Costco": [1, 2]
})

df
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵
# Turn Aldi, Walmart, Costco into values of "store"
df.melt(id_vars=["fruit"],
        value_vars=["Aldi", "Walmart", "Costco"],
        var_name='store')
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵

? 13:重新命名聚合列

我們經常會使用分組聚合的功能,如果要為聚合分配新名稱,可以使用name = (column, agg_method)方法:

import pandas as pd

df = pd.DataFrame({"size": ["S", "S", "M", "L"],
                   "price": [44, 29.99, 10, 19]})

df.groupby('size').agg({'price': 'mean'})
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵
# Assign name to the aggregation
df.groupby('size').agg(
    mean_price=('price', 'mean')
)
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵

? 14:填充空值

pandas.DataFrame.combine_first對兩個 DataFrame 進行聯合操作,實現合併的功能。

combine_first()方法根據 DataFrame 的行索引和列索引,對比兩個 DataFrame 中相同位置的資料,優先取非空的資料進行合併。

如果呼叫combine_first()方法的 df1 中資料非空,則結果保留 df1 中的資料,如果 df1 中的資料為空值且傳入combine_first()方法的 df2 中資料非空,則結果取 df2 中的資料,如果 df1 和 df2 中的資料都為空值,則結果保留 df1 中的空值(空值有三種:np.nanNonepd.NaT)。

即使兩個 DataFrame 的形狀不相同也不受影響,聯合時主要是根據索引來定位資料的位置。

import pandas as pd

store1 = pd.DataFrame({
    "orange": [None, 5, 9],
    "apple": [4, None, 12]
})

store2 = pd.DataFrame({
    "orange": [31, 52, 91],
    "apple": [11, 71, 21]
})

# Fill null values of the store1 with values at the same
# locations from store2
store1.combine_first(store2)
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵

? 15:過濾 DataFrame 中的列

我們可以根據名稱中的子字串過濾 pandas DataFrame 的列,具體是使用 pandas 的DataFrame.filter功能。

import pandas as pd

df = pd.DataFrame({'Temp': ['Hot', 'Cold', 'Warm', 'Cold'],
                   'Degree': [35, 3, 15, 2]})
print(df)
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵
df = pd.get_dummies(df, columns=['Temp'])
print(df)
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵
print(df.filter(like='Temp', axis=1))
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵

? 16:自動轉換資料型別

對於 DataFrame 中的列,我們可以調整其資料型別,使用convert_dtypes()可以快速將它轉換為我們需要的資料型別。

import pandas as pd
import numpy as np

df = pd.DataFrame(
    {
        "a": pd.Series([1, 2, 3], dtype=np.dtype("int32")),
        "b": pd.Series(["x", "y", "z"], dtype=np.dtype("O")),
        "c": pd.Series([True, False, np.nan], dtype=np.dtype("O")),
        "d": pd.Series(["h", "i", np.nan], dtype=np.dtype("O")),
        "e": pd.Series([10, np.nan, 20], dtype=np.dtype("float")),
        "f": pd.Series([np.nan, 100.5, 200], dtype=np.dtype("float")),
    }
)

df.dtypes
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵
new_df = df.convert_dtypes()
new_df.dtypes
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵

? 17:將新列分配給 DataFrame

在我們處理資料的時候,有時需要根據某個列進行計算得到一個新列,以便後續使用,相當於是根據已知列得到新的列,這個時候assign函式非常方便。

import pandas as pd

time_sentences = ["Saturday: Weekend (Not working day)",
                  "Sunday: Weekend (Not working day)",
                  "Monday: Doctor appointment at 2:45pm.",
                  "Tuesday: Dentist appointment at 11:30 am.",
                  "Wednesday: basketball game At 7:00pm",
                  "Thursday: Back home by 11:15 pm.",
                  "Friday: Take the train at 08:10 am."]

df = pd.DataFrame(time_sentences, columns=['text'])

# Use Assign instead of using direct assignment 
# df['text'] = df.text.str.lower()
# df['text_len'] = df.text.str.len()
# df['word_count'] = df.text.str.count(" ") + 1
# df['weekend'] = df.text.str.contains("saturday|sunday", case=False)
print((
    df
    .assign(text=df.text.str.lower(),
            text_len=df.text.str.len(),
            word_count=df.text.str.count(" ") + 1,
            weekend=df.text.str.contains("saturday|sunday", case=False),
           )
))
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵

? 18:讀取 HTML 表格

我們可以使用.read_html()可用於快速合併來自各種網站的表格,我們不用關心它是如何抓取網站HTML的。

import pandas as pd

# 抓取股票資料
table = pd.read_html(
    "http://vip.stock.finance.sina.com.cn/q/go.php/vComStockHold/kind/jjzc/index.phtml"
)

table[0].head()
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵

? 19:nlargest 和 nsmallest

如果我們需要對資料欄位進行排序,可以使用.sort_values(),但是它會對所有資料排序,如果我們要獲取最大或者最小的 n 個數,可以利用.nlargest().nsmallest()

這裡用到的資料集是 ?IMDB電影評分資料集,大家可以透過 ShowMeAI 的百度網盤地址下載。

? 實戰資料集下載(百度網盤):公✦眾✦號『ShowMeAI研究中心』回覆『實戰』,或者點選 這裡 獲取本文 [65]資深資料科學家整理的21個Pandas技巧imdbratings資料集

ShowMeAI官方GitHubhttps://github.com/ShowMeAI-Hub

import pandas as pd

df = pd.read_csv('data/imdbratings.csv',
                 usecols=['star_rating', 'title', 'genre', 'duration'])

print(df.head())
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵
print(df.nlargest(5, "duration"))
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵
print(df.nsmallest(5, "duration"))
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵

? 20:建立排序列

pandas 的DataFrame.rank()函式可以返回欄位每個取值的排名。

在以下示例中,建立了一個新的排名列,該列按學生的分數對學生進行排名:

import pandas as pd

df = pd.DataFrame({'Students': ['John', 'Smith', 'Patrick', 'Bob', 'Jose'],
                   'Marks': [80, 56, 95, 75, 45]})
print(df)
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵
df["Rank"] = df["Marks"].rank(ascending=False)
print(df)
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵

? 21:DataFrame 中的顏色值

可以為 dataframe 新增顏色樣式,增加更多的可讀性。Pandas 具有 style 屬性,可以設定顏色應用於 DataFrame。

import pandas as pd

df = pd.DataFrame({'Students': ['John', 'Smith', 'Patrick', 'Bob', 'Jose'],
                   'Physics': [80, 56, 95, 75, 45], 
                   'Mathematics': [90, 85, 55, 65, 75]})

df.set_index('Students', inplace=True)
df
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵
def pass_condition(val):
    color = 'blue' if val > 70 else 'red'
    return f"background-color: {color}"

df.style.applymap(pass_condition)
高手系列!資料科學傢俬藏pandas高階用法大全 ⛵

參考資料

推薦閱讀

高手系列!資料科學傢俬藏pandas高階用法大全 ⛵

相關文章