1. 程式人生 > 實用技巧 >pandas高階操作

pandas高階操作

替換操作

  • 替換操作可以同步作用於Series和DataFrame中
  • 單值替換
    • 普通替換: 替換所有符合要求的元素:to_replace=15,value='e'
    • 按列指定單值替換: to_replace={列標籤:替換值} value='value'
  • 多值替換
    • 列表替換: to_replace=[] value=[]
    • 字典替換(推薦) to_replace={to_replace:value,to_replace:value}

import numpy as np
import pandas as pd
from pandas import DataFrame

df = DataFrame(data=np.random.randint(0,50,size=(7,5)))

df

df.replace(to_replace=6,value='six') #單值替換

df.replace(to_replace={6:'six',2:'two'}) #多值替換

df.replace(to_replace={0:2},value='two') #定列替換

對映操作

  • 概念:建立一個對映關係列表,把values元素和一個特定的標籤或者字串繫結(給一個元素值提供不同的表現形式)
  • 建立一個df,兩列分別是姓名和薪資,然後給其名字起對應的英文名
dic = {
    'name':['jay','tom
','jay'], 'salary':[1000,2000,1000] } df = DataFrame(data=dic) df


#給jay和tom起兩個中文名字
dic = {#對映關係表:表明了對映關係
'jay':'張三',
'tom':'李四'
}
df['c_name'] = df['name'].map(dic)
df




運算工具

  • 超過300部分的錢繳納50%的稅,計算每個人的稅後薪資
  • map是Series的方法,只能被Series呼叫

def after_sal(s):
    return s - (s-300)*0.5
df['after_sal
'] = df['salary'].map(after_sal) df

Series的方法apply也可以像map一樣充當運算工具

  • apply充當運算工具效率要遠遠高於map

def after_sal(s):
return s - (s-300)*0.5
df['after_sal'] = df['salary'].apply(after_sal)
df

排序實現的隨機抽樣

  • take()
  • np.random.permutation()
df = DataFrame(data=np.random.randint(0,100,size=(100,3)),columns=['A','B','C'])
np.random.permutation(3) #返回0-2之間的亂序序列
array([2, 0, 1])

#1.對原始資料進行打亂
#打亂:是對索引打亂
#task的axis和drop系列的函式
df.take(indices=np.random.permutation(3),axis=1)

#對行列索引進行打亂且進行隨機抽樣
df.take(indices=np.random.permutation(3),axis=1).take(indices=np.random.permutation(100),axis=0)[0:20]

資料的分類處理

  • 資料分類處理的核心:

    • groupby()函式
    • groups屬性檢視分組情況
df = DataFrame({'item':['Apple','Banana','Orange','Banana','Orange','Apple'],
                'price':[4,3,3,2.5,4,2],
               'color':['red','yellow','yellow','green','green','green'],
               'weight':[12,20,50,30,20,44]})
df


#提供一個分組條件,想要對水果的種類分組
df.groupby(by='item')

<pandas.core.groupby.groupby.DataFrameGroupBy object at 0x11950b278>

#檢視分組結果
df.groupby(by='item').groups

{'Apple': Int64Index([0, 5], dtype='int64'),
 'Banana': Int64Index([1, 3], dtype='int64'),
 'Orange': Int64Index([2, 4], dtype='int64')}

#分組聚合:計算每一種水果的平均價格
df.groupby(by='item').mean()['price']#不推薦

item
Apple     3.00
Banana    2.75
Orange    3.50
Name: price, dtype: float64

#推薦
df.groupby(by='item')['price'].mean()

item
Apple     3.00
Banana    2.75
Orange    3.50
Name: price, dtype: float64

#將每一種水果的平均價格計算出來然後彙總到源資料中
mean_price_s = df.groupby(by='item')['price'].mean()
mean_price_s

item
Apple     3.00
Banana    2.75
Orange    3.50
Name: price, dtype: float6

dic = mean_price_s.to_dict()
dic

#求出每一種顏色水果的平均重量,將其彙總到源資料中
mean_weight_s = df.groupby(by='color')['weight'].mean()
mean_weight_s

color
green     31.333333
red       12.000000
yellow    35.000000
Name: weight, dtype: float64

df['color_mean_weight'] = df['color'].map(mean_weight_s.to_dict())
df

高階資料聚合

  • 使用groupby分組後,也可以使用transform和apply提供自定義函式實現更多的運算
  • df.groupby('item')['price'].sum() <==> df.groupby('item')['price'].apply(sum)
  • transform和apply都會進行運算,在transform或者apply中傳入函式即可
  • transform和apply也可以傳入一個lambda表示式
def my_mean(s):
    sum = 0
    for i in s:
        sum += i
    return sum / len(s)

df.groupby(by='item')['price'].transform(my_mean)
0    3.00
1    2.75
2    3.50
3    2.75
4    3.50
5    3.00
Name: price, dtype: float64

df.groupby(by='item')['price'].apply(my_mean)
item
Apple     3.00
Banana    2.75
Orange    3.50
Name: price, dtype: float64

  • apply和transform的區別:
    • transform返回的結果是經過對映後的結果
    • apply返回的是沒有經過對映的結果

資料載入

  • 讀取type-.txt檔案資料

df = pd.read_csv('./data/type-.txt') #文字第一行成為了列索引 這不是我們想要的
df

df = pd.read_csv('./data/type-.txt',header=None)
df

df = pd.read_csv('./data/type-.txt',header=None,sep='-')
df

df.shape

(2, 1)

讀取資料庫中的資料

#連線資料庫,獲取連線物件
import sqlite3 as sqlite3
conn = sqlite3.connect('./data/weather_2012.sqlite')

#讀取庫表中的資料值
sql_df=pd.read_sql('select * from weather_2012',conn)
sql_df

#將一個df中的資料值寫入儲存到db
df.to_sql('dddfff',conn)

pd.read_sql('select * from dddfff',conn)

透視表

  • 透視表是一種可以對資料動態排布並且分類彙總的表格格式。或許大多數人都在Excel使用過資料透視表,也體會到它的強大功能,而在pandas中它被稱作pivot_table。
  • 透視表的優點:
    • 靈活性高,可以隨意定製你的分析計算要求
    • 脈絡清晰易於理解資料
    • 操作性強,報表神器

df = pd.read_csv('./data/透視表-籃球賽.csv')
df

pivot_table有四個最重要的引數index、values、columns、aggfunc

  • index引數:分類彙總的分類條件
    • 每個pivot_table必須擁有一個index。如果想檢視哈登對陣每個隊伍的得分則需要對每一個隊進行分類並計算其各類得分的平均值:
  • 想看看哈登對陣同一對手在不同主客場下的資料,分類條件為對手和主客場
df.pivot_table(index=['對手','主客場'])

values引數:需要對計算的資料進行篩選

  • 如果我們只需要哈登在主客場和不同勝負情況下的得分、籃板與助攻三項資料:
df.pivot_table(index=['主客場','勝負'],values=['得分','籃板','助攻'])
  • Aggfunc引數:設定我們對資料聚合時進行的函式操作
    • 當我們未設定aggfunc時,它預設aggfunc='mean'計算均值。
  • 還想獲得james harden在主客場和不同勝負情況下的總得分、總籃板、總助攻時:
df.pivot_table(index=['主客場','勝負'],values=['得分','籃板','助攻'],aggfunc='sum')

Columns:可以設定列層次欄位

  • 對values欄位進行分類
#獲取所有隊主客場的總得分
df.pivot_table(index='主客場',values='得分',aggfunc='sum')

#檢視主客場下的總得分的組成元素是誰
df.pivot_table(index='主客場',values='得分',aggfunc='sum',columns='對手',fill_value=0)

交叉表

  • 是一種用於計算分組的特殊透檢視,對資料進行彙總
  • pd.crosstab(index,colums)
    • index:分組資料,交叉表的行索引
    • columns:交叉表的列索引
import pandas as pd
from pandas import DataFrame

df = DataFrame({'sex':['man','man','women','women','man','women','man','women','women'],
               'age':[15,23,25,17,35,57,24,31,22],
               'smoke':[True,False,False,True,True,False,False,True,False],
               'height':[168,179,181,166,173,178,188,190,160]})
df
#求出各個性別抽菸的人數

pd.crosstab(index=df.smoke,columns=df.sex)

#求出各個年齡段抽菸人情況

pd.crosstab(df.age,df.smoke)