Python: 如何將pandas.DataFrame從寬資料轉為長資料? df_melt = pd.melt(df, id_vars=[‘name’, ‘gender’], var_name=’time’, value_name=’score’) ; seaborn繪圖

加入好友
加入社群
Python: 如何將pandas.DataFrame從寬資料轉為長資料? df_melt = pd.melt(df, id_vars=['name', 'gender'], var_name='time', value_name='score') ; seaborn繪圖 - 儲蓄保險王

dic={
“name” : [“甲”,”乙”,”丙”],
“gender”: [“M”,”F”,”M”],
“time1” : [10,12,11],
“time2” : [15,17,17],
“time3” : [20,22,21]
}
import pandas as pd
df = pd.DataFrame(dic)

df_melt = pd.melt(df, id_vars=[‘name’, ‘gender’],
var_name=’time’, value_name=’score’)

“””
這個函式的意思是將 id 和 gender 兩個欄位視為身份識別,
time1、time2、time3 三個欄位則視為同一個變數,
將它們轉換成一個新的欄位 time,欄位
score 則為原先三個欄位的數值。
“””
df_melt2 = pd.melt(df, id_vars=[‘name’, ‘gender’],
value_vars=[‘time1’, ‘time2’, ‘time3’],
var_name=’time’, value_name=’score’)
“””
id_vars:指定不要進行重塑的欄位
value_vars:指定哪些欄位要重塑成單一欄位

這兩種寫法最大的差異點在於value_vars參數。在第一個寫法中,var_name參數會自動將所有非id_vars的欄位都視為要重塑的欄位。而在第二個寫法中,需要使用value_vars參數明確指定要重塑的欄位。因此,第一個寫法較為簡潔,但如果有些欄位不想重塑,就需要使用第二種寫法。使用第二種寫法,不在id_vars,也不在value_vars的欄位,會自動被捨棄。
“””
df_stack = df.set_index([‘name’, ‘gender’]).stack().reset_index()
df_stack.columns = [‘name’, ‘gender’, ‘time’, ‘score’]

Python: 如何將pandas.DataFrame從寬資料轉為長資料? df_melt = pd.melt(df, id_vars=['name', 'gender'], var_name='time', value_name='score') ; seaborn繪圖 - 儲蓄保險王

原本df(寬資料):

Python: 如何將pandas.DataFrame從寬資料轉為長資料? df_melt = pd.melt(df, id_vars=['name', 'gender'], var_name='time', value_name='score') ; seaborn繪圖 - 儲蓄保險王

df_melt = pd.melt(df, id_vars=[‘name’, ‘gender’],
var_name=’time’, value_name=’score’)

df_melt2 = pd.melt(df, id_vars=[‘name’, ‘gender’],
value_vars=[‘time1’, ‘time2’, ‘time3’],
var_name=’time’, value_name=’score’)

df_melt, df_melt2 一樣:

Python: 如何將pandas.DataFrame從寬資料轉為長資料? df_melt = pd.melt(df, id_vars=['name', 'gender'], var_name='time', value_name='score') ; seaborn繪圖 - 儲蓄保險王

df_stack = df.set_index([‘name’, ‘gender’]).stack().reset_index()
df_stack.columns = [‘name’, ‘gender’, ‘time’, ‘score’]

效果相近,排列的順序不一樣而已

Python: 如何將pandas.DataFrame從寬資料轉為長資料? df_melt = pd.melt(df, id_vars=['name', 'gender'], var_name='time', value_name='score') ; seaborn繪圖 - 儲蓄保險王

df_stack = df.set_index([‘name’, ‘gender’]).stack().reset_index()

拆為分解動作:

  1. set_index()將[‘name’, ‘gender’]都變成index:

Python: 如何將pandas.DataFrame從寬資料轉為長資料? df_melt = pd.melt(df, id_vars=['name', 'gender'], var_name='time', value_name='score') ; seaborn繪圖 - 儲蓄保險王

      2. stack()將非index的資料都做堆疊:

Python: 如何將pandas.DataFrame從寬資料轉為長資料? df_melt = pd.melt(df, id_vars=['name', 'gender'], var_name='time', value_name='score') ; seaborn繪圖 - 儲蓄保險王

     3. reset_index()將原本變成index的欄位,再推出來變成資料

Python: 如何將pandas.DataFrame從寬資料轉為長資料? df_melt = pd.melt(df, id_vars=['name', 'gender'], var_name='time', value_name='score') ; seaborn繪圖 - 儲蓄保險王

將寬資料轉換成長資料

有利於 # seaborn 繪圖

推薦hahow線上學習python: https://igrape.net/30afN

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np

# 創建資料
x = np.linspace(0, 2 * np.pi, 50)
df_sin = pd.DataFrame({‘x’: x, ‘y’: np.sin(x), ‘func’: ‘sin’})
df_cos = pd.DataFrame({‘x’: x, ‘y’: np.cos(x), ‘func’: ‘cos’})

#注意:以上兩個df的欄位名稱都是’y’,而非’y1′, ‘y2’ 

#concat()才能做出跟melt()一樣的效果

#若欄位名稱不一樣,#concat後

# y1: sin, sin ….,NaN,NaN…
# y2: NaN,NaN…,cos,cos…

# concat 跟 melt 仍有本質上的差異

df = pd.concat([df_sin, df_cos]) #上下串接

#若原始資料是寬資料(三欄分別為x, sin, cos)

#就可以用melt(),做出concat()的效果

#df2 = pd.melt(df, id_vars=[‘x’],value_vars=[‘sin’, ‘cos’])

 

# 繪製圖形
# sns.relplot(data=df, x=’x’, y=’y’,hue=”func”)
sns.relplot(x=’x’, y=’y’, kind=’scatter’,col=’func’, data=df)

plt.savefig(‘plot.png’)

Python: 如何將pandas.DataFrame從寬資料轉為長資料? df_melt = pd.melt(df, id_vars=['name', 'gender'], var_name='time', value_name='score') ; seaborn繪圖 - 儲蓄保險王

這段程式碼使用了 Seaborn 的圖形等級函式 sns.relplot() 來繪製圖形,其中參數 x 設定 x 軸資料,y 設定 y 軸資料,kind 設定繪製的圖形種類為散點圖,col 則是指定分類列。

由於資料集包含了 sin 和 cos 兩個函數的資料,col='func' 的設定讓 Seaborn 將數據按照 func 欄位的值(sin 或 cos)分為兩個小圖,分別繪製在同一個畫布上,這樣就能夠方便地比較兩個函數的形狀和變化趨勢。

因此,最終繪製出的圖形是一個帶有兩個子圖的散點圖,每個子圖分別繪製了一個函數的數據點。最終的圖形可以使用 plt.savefig() 來保存到圖片檔案中。

先看原始資料df:
Python: 如何將pandas.DataFrame從寬資料轉為長資料? df_melt = pd.melt(df, id_vars=['name', 'gender'], var_name='time', value_name='score') ; seaborn繪圖 - 儲蓄保險王
輸出圖片:
Python: 如何將pandas.DataFrame從寬資料轉為長資料? df_melt = pd.melt(df, id_vars=['name', 'gender'], var_name='time', value_name='score') ; seaborn繪圖 - 儲蓄保險王
 

 

加入好友
加入社群
Python: 如何將pandas.DataFrame從寬資料轉為長資料? df_melt = pd.melt(df, id_vars=['name', 'gender'], var_name='time', value_name='score') ; seaborn繪圖 - 儲蓄保險王

儲蓄保險王

儲蓄險是板主最喜愛的儲蓄工具,最喜愛的投資理財工具則是ETF,最喜愛的省錢工具則是信用卡

You may also like...

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *