Pandas行列轉換的4大技巧

公衆號:尤而小屋
作者:Peter
編輯:Peter

大家好,我是Peter~

本文介紹的是Pandas中4個行列轉換的方法,包含:

  • melt
  • 轉置T或者transpose
  • wide_to_long
  • explode(爆炸函數)

最後回答一個讀者朋友問到的數據處理問題。

Pandas行列轉換

pandas中有多種方法能夠實現行列轉換:

導入庫

import pandas as pd
import numpy as np

函數melt

melt的主要參數:

pandas.melt(frame, 
            id_vars=None, 
            value_vars=None, 
            var_name=None, 
            value_name='value',
            ignore_index=True,  
            col_level=None)

下面解釋參數的含義:

  • frame:要處理的數據框DataFrame。

  • id_vars:表示不需要被轉換的列名

  • value_vars:表示需要轉換的列名,如果剩下的列全部都需要進行轉換,則不必寫

  • var_name和value_name:自定義設置對應的列名,相當於是取新的列名

  • igonore_index:是否忽略原列名,默認是True,就是忽略了原索引名,重新生成0,1,2,3,4....的自然索引

  • col_level:如果列是多層索引列MultiIndex,則使用此參數;這個參數少用

模擬數據

# 待轉換的數據:frame
df = pd.DataFrame({"col1":[1,1,1,1,1],
                   "col2":[3,3,3,3,3],
                   "col3":["a","a","a","b","b"]
                  })
df

id_vars

value_vars

上面兩個參數的同時使用:

同時轉換多個列屬性:

var_name和value_name

pd.melt(
    df,
    id_vars=["col1"],  # 不變
    value_vars=["col3"],  # 轉變
    var_name="col4",  # 新的列名
    value_name="col5" # 對應值的新列名
)

ignore_index

默認情況下是生成自然索引:

可以改成False,使用原來的索引:

轉置函數

pandas中的T屬性或者transpose函數就是實現行轉列的功能,準確地說就是轉置

簡單轉置

模擬了一份數據,查看轉置的結果:

使用transpose函數進行轉置:

還有另一個方法:先對值values進行轉置,再把索引和列名進行交換:

最後看一個簡單的案例:

wide_to_long函數

字面意思就是:將數據集從寬格式轉換爲長格式

wide_to_long(
    df,
    stubnames,
    i,
    j,
    sep: str = "",
    suffix: str = "\\d+"

參數的具體解釋:

  • df:待轉換的數據框
  • stubnames:寬表中列名相同的存部分
  • i:要用作 id 變量的列
  • j:給長格式的“後綴”列設置 columns
  • sep:設置要刪除的分隔符。例如 columns 爲 A-2020,則指定 sep='-' 來刪除分隔符。默認爲空。
  • suffix:通過設置正則表達式取得“後綴”。默認'\d+'表示取得數字後綴。沒有數字的“後綴”可以用'\D+'來取得

模擬數據

轉換過程

使用函數實施轉換:

設置多層索引

先模擬一份數據:

如果不習慣多層索引,可以轉成下面的格式:

sep和suffix

df5 = pd.DataFrame({
    'a': [1, 1, 2, 2, 3, 3, 3],
    'b': [1, 2, 2, 3, 1, 2, 3],
    'stu_one': [2.8, 2.9, 1.8, 1.9, 2.2, 2.3, 2.1],
    'stu_two': [3.4, 3.8, 2.8, 2.4, 3.3, 3.4, 2.9]
})
df5
pd.wide_to_long(
    df5, 
    stubnames='stu', 
    i=['a', 'b'], 
    j='number',
    sep='_', # 列名中存在連接符時使用;默認爲空
    suffix=r'\w+')  # 基於正則表達式的後綴;默認是數字\d+;這裏改成\w+,表示字母

爆炸函數-explode

explode(column, ignore_index=False)

這個函數的參數就只有兩個:

  • column:待爆炸的元素
  • ignore_index:是否忽略索引;默認是False,保持原來的索引

模擬數據

單個字段爆炸

對單個字段實施爆炸過程,將寬錶轉成長表:

參數ignore_index

多個字段爆炸

連續對多個字段實施爆炸的過程:

讀者解疑

在這裏回答一個讀者的問題,數據採用模擬的形式。有下面的這樣一份數據,需求:

每個shop下每個fruit在各自shop的佔比

fruit = pd.DataFrame({
    "shop":["shop1","shop3","shop2","shop3",
            "shop2","shop1","shop3","shop2",
            "shop3","shop2","shop3","shop2","shop1"],
    "fruit":["蘋果","葡萄","香蕉","蘋果",
             "葡萄","橘子","梨","哈密瓜",
             "葡萄","香蕉","蘋果","葡萄","橘子"],
    "number":[100,200,340,150,
              200,300,90,80,340,
              150,200,300,90]})
fruit

首先我們是需要統計每個shop每個fruit的銷量

方法1:多步驟

方法1採用的是多步驟解決:

1、每個shop的總銷量

2、增加總和shop_sum列

3、生成佔比

方法2:使用transform函數

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