以題代學(xué)—pandas數(shù)據(jù)處理速成

問題1 計算漲幅

  • 題目描述
    一個 df 有三個列需要進行計算,change_type 值 為1和0, 1為漲價,0為降價, price為現(xiàn)價, changed為漲降價的絕對值, 現(xiàn)求:漲降價的比例, 精確到0位,無小數(shù)位。
  • 知識點提要
    (1)apply + lambda函數(shù)
    (2)map + format
    (3)區(qū)分apply和map
    傳送門:pandas常用知識點
  • 解法
#1.構(gòu)造數(shù)據(jù)
import pandas as pd
df = pd.DataFrame({'change_type' : [1,1,0,0,1,0],
                    'price' : [100, 90, 50, 120, 150, 200],
                    'changed' : [10,8,4,11,14,10]})
#通過字典創(chuàng)建dataframe
#2.編寫函數(shù)
#第一個函數(shù)計算漲幅
#第二個函數(shù)轉(zhuǎn)換為要求格式的百分比
func1 = lambda x: x['changed']/x['price'] if x['change_type'] == 1 else -x['changed']/x['price']
#注意1,結(jié)合apply時候設(shè)置axis=1參數(shù),否則報錯。
#注意2,pandas結(jié)合lambda函數(shù)可以針對整個df進行操作。
func2 = lambda x: format(x,'.0%')
#注意格式處理的方法,有兩種一種是%占位符,一種是format,個人認為現(xiàn)用現(xiàn)百度。
#3.計算
df['percentage'] = df.apply(func1,axis=1).map(lambda x:format(x,'.0%'))

問題2 同一個dataframe里根據(jù)某列值更改另一列的值

  • 題目描述
    有一個dataframe存儲了兩列數(shù)據(jù),一列點評ID,一列點評狀態(tài),要求點評ID為null的點評狀態(tài)賦值為0,點評ID不為null的賦值為1。
  • 知識點提要
    (1)apply+自定義函數(shù)(def)
    (2)loc + 數(shù)據(jù)框賦值 + ~用法
  • 解法
#1.構(gòu)造數(shù)據(jù)
df = pd.DataFrame(
    {"has_comment_or_not":['0','0','0','1','0','0'],
    "comment_status":["null","null","120047007","null","null","122121"]}
    )
#2.解法1:編寫函數(shù)求解
##2.1 編寫傳統(tǒng)函數(shù)
def change_status(s):
    if s.comment_status == 'null':
        return 0
    else:
        return 1
#這種做法更適合復(fù)雜的業(yè)務(wù)場景,用編寫函數(shù)的形式做一套流程化的東西,s就可以認為是數(shù)據(jù)框,再apply的時候設(shè)置axis=1。
##2.2應(yīng)用函數(shù)
df['has_comment_or_not'] = df5.apply(change_status,axis=1)
#3.解法2:loc求解
##篩選條件,分等和不等兩種
df.loc[df['comment_status'] == 'null','has_comment_or_not'] = 0
df.loc[~(df['comment_status'] == 'null'),'has_comment_or_not'] = 1

問題3 用另一個dataframe的值替換當前dataframe的值

  • 題目描述:
    有一個df1,里邊存儲著英文的蔬菜名,有另外一個df2,里邊存儲著蔬菜名和對應(yīng)的大類別,要求按照df2的蔬菜名和大類別對應(yīng)關(guān)系給df1的蔬菜名重新賦值。
    注意:如果df2中沒有df1中的蔬菜名那么蔬菜1保留原值;
    如果df2中對應(yīng)的大類別為空,那么df1中的蔬菜名保持原值;
    其他情況進行替換。
  • 知識點提要
    (1)map+字典
    (2)map+dataframe
  • 解法
#1.構(gòu)造數(shù)據(jù)
df1 = pd.DataFrame({'ItemType1':['redTomato',
'whitePotato',
'yellowPotato',
'greenCauliflower',
'yellowCauliflower',
'yelloSquash',
'redOnions',
'YellowOnions',
'WhiteOnions',
'yellowCabbage',
'GreenCabbage']})
df2 = pd.DataFrame({'ItemType2':['whitePotato',       
'yellowPotato',      
'redTomato',         
'yellowCabbage',   
'GreenCabbage',    
'yellowCauliflower',  
'greenCauliflower',  
'YellowOnions',  
'WhiteOnions',
'yelloSquash',
'redOnions'],
'newType':['Potato',
'Potato',
'Tomato',
'',
'',
'yellowCauliflower',
'greenCauliflower',
'Onions',
'Onions',
'Squash',
'Onions']})
#2.思路1:用“map+字典”解決
#首先需要將df2的兩列轉(zhuǎn)換為字典,直接轉(zhuǎn)肯定是沒有函數(shù)了,
#首先添加一個輔助列,把二者對應(yīng)為字典,
#然后根據(jù)字典的特征,構(gòu)造一個大字典。
#然后map掉。
df2['map_1'] = df2.apply(lambda x: {x['ItemType2']:x['newType']} if x['newType'] else {x['ItemType2']:x['ItemType2']},axis=1)
new_dict = {}
for dict1 in df2['map_1'].tolist():
    for k,v in dict1.items():
        if k not in new_dict:
            new_dict[k] = v
        else:
            new_dict[k].append(v)
df1['ItemType1'] = df1['ItemType1'].map(new_dict)
#3.思路2:map + df用法
#這個思路和上面的類似,只不過map可以和df結(jié)合使用,這里的df要設(shè)置index,相當于key
#首先需要把空格替換為原值
df2 = df2.set_index('ItemType2')
df2.loc[df2['newType'] == '','newType'] = df2.loc[df2['newType'] == ''].index 
df1['ItemType1'] = df1['ItemType1'].map(df2.newType)

問題4 銷售數(shù)據(jù)的聚合統(tǒng)計

  • 題目描述:
    有一個tsv文件存儲著某公司的銷售數(shù)據(jù),讀入這個tsv,并對數(shù)據(jù)做以下統(tǒng)計:
    (1)統(tǒng)計下單最多的商品(item_name)
    (2)統(tǒng)計有多少種商品被下單
    (3)統(tǒng)計下單最多的商品(choice_description)
    (4)計算所有商品的總收入
    (5)統(tǒng)計訂單數(shù)
    (6)統(tǒng)計所有訂單的平均收入

  • 知識點提要
    (1)groupby + apply/map
    (2)nunique
    (3)sort_values
    (4)astype

  • 解法

df6 = pd.read_csv(r'C:/Users/wangxiaowei11772/Desktop/exercise_data/chipotle.tsv',sep='\t')
#下單最多的商品(item_name)
df6.groupby('item_name').quantity.apply(sum).sort_values(ascending=False).index[0]
#統(tǒng)計有多少種商品被下單
df6[df6['quantity'] > 0].item_name.nunique()
#下單最多的商品(choice_description)
df6[['choice_description','quantity']].dropna().groupby('choice_description').agg({'quantity':sum}).sort_values(by= 'quantity', ascending = False).head(1).index
#將item_price轉(zhuǎn)換為浮點數(shù)
df6['item_price'] = df6.item_price.apply(lambda x: x[1:]).map(float)
#計算商品的總收入
df6['sum_revenue'] = df6['quantity']*df6['item_price'].astype(float)
df6['sum_revenue'].sum()
#直接寫sum有問題是對每一個元素求sum相當于沒求,所以還是先增列再求和比較穩(wěn)妥
#統(tǒng)計訂單數(shù)
df6.order_id.nunique()
#統(tǒng)計所有訂單的平均收入
round(df6.groupby('order_id').sum_revenue.sum().mean(),2)

問題5 統(tǒng)計每位學(xué)生平均分數(shù)最高的課程

  • 題目描述
    有一個數(shù)據(jù)框存儲著學(xué)生的考試成績,但考試成績分為期中和期末兩次,計算每一個同學(xué)的平均分。
  • 知識點提要
    (1)reset_index()
    (2)idxmax和iloc的使用
  • 解法
#1.創(chuàng)建數(shù)據(jù)框
dict1 = {'ID': [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3],
         'cls': ['math', 'math', 'en', 'en', 'math', 'math', 'en', 'en', 'math', 'math', 'en', 'en'],
         'score': [95, 98, 86, 85, 67, 87, 89, 97, 87, 86, 89, 87]}
df6 = pd.DataFrame(dict1)
#2.計算平均分數(shù)
df7 = df6.groupby(['ID','cls']).score.mean().reset_index()
#3.找出最高分數(shù)的課程
df7.iloc[df7.groupby(['ID']).score.idxmax(),1:3]

問題6 數(shù)據(jù)框的轉(zhuǎn)置

  • 題目
    這個問題是一道休閑題,算是這個系列到這的一個休息。問題有一個數(shù)據(jù)框,如何實現(xiàn)行和列的轉(zhuǎn)置。
  • 知識點提要
    (1).T
    (2)stack和unstack
  • 解法
#1.構(gòu)造數(shù)據(jù)
import pandas as pd
import numpy as np
tmp = np.arange(16).reshape(4,4)
columns = ['a','b','c','d']
indexs = ['aa','bb','cc','dd']
df1 = pd.DataFrame(tmp,columns=columns,index=indexs)
#2.解法
#2.1 最簡單解法
df1.T
#dataframe也可以用轉(zhuǎn)置這個很神奇
#2.2 stack解法
df2 = df1.stack()
df2 = df2.unstack(level=0)
#stack和unstack有個參數(shù)level主要是控制index的層次

問題7 缺失值的處理

  • 題目
    現(xiàn)在有一個數(shù)據(jù)框,里邊由于數(shù)據(jù)存儲操作問題,存在很多缺失值,要如何處理這些缺失值。缺失值處理包括的內(nèi)容比較多,比如缺失值的統(tǒng)計,缺失值的刪除,缺失值的填充等等。具體題目包括:
    (1)統(tǒng)計具有缺失值的列
    (2)統(tǒng)計每一列有幾個缺失值
    (3)刪除city列為空的數(shù)據(jù)
    (4)處理age列的缺失值
  • 知識點提要
    (1)isna()
    (2)any()
    (3)fillna()
  • 解法
#構(gòu)造數(shù)據(jù)
import pandas as pd
import numpy as np
index = pd.Index(data=["Tom", "Bob", "Mary", "James", "Andy", "Alice"], name="name")
data = {
    "age": [18, 30, np.nan, 40, np.nan, 30],
    "city": ["BeiJing", "ShangHai", "GuangZhou", "ShenZhen", np.nan, " "],
    "sex": [None, "male", "female", "male", np.nan, "unknown"],
    "birth": ["2000-02-10", "1988-10-17", None, "1978-08-08", np.nan, "1988-10-17"]
}
df7 = pd.DataFrame(data, index=index)
#1.統(tǒng)計有缺失值的列
df7.isna().any()
#2.統(tǒng)計每一列有幾個缺失值
df7.isna().sum()
#3.刪除city列為空的數(shù)據(jù)
df7.dropna(subset=['city'],how='any')
#4.數(shù)據(jù)變量缺失值的填充
df7['age'].fillna(df7['age'].mean(),inplace=True)
##這里需要注意的是如果是mode可能有很多個數(shù),用個切片[0],把數(shù)據(jù)取出來

問題8 數(shù)據(jù)抽樣

等我補充

問題9 計算文本的平均長度

  • 題目
    現(xiàn)在有一個數(shù)據(jù)框,存的數(shù)據(jù)包括id和text兩列,現(xiàn)在要求平均文本你長度。
  • 知識點提要
    (1)lambda
    (2)mean
  • 解法
#1.構(gòu)造數(shù)據(jù)
dict1 = {'Id':list(range(5)),
         'text':['ab','a','abcd','abcde','aa']}
df1 = pd.DataFrame(dict1)
#2.求平均值
df1.text.apply(lambda x: len(x)).mean()

問題10 篩選出具有5個以上不同數(shù)據(jù)的所有數(shù)據(jù)

  • 題目
    現(xiàn)在有一個數(shù)據(jù)框,包括姓名和number兩列數(shù)據(jù),現(xiàn)在要求篩選出來具有五個以上number值的所有數(shù)據(jù),注意篩選出來的數(shù)據(jù)要包括姓名和number的所有數(shù)據(jù)。
  • 知識點提要
    (1)set_index
    (2)dataframe切片
  • 解法
#1.構(gòu)造數(shù)據(jù)
import numpy as np
import pandas as pd
import random
name_list = np.array([['王大偉']*7,['聶小萌']*6,['肖大潔']*5,['徐小花']*3])
name_list = [y for x in name_list.flatten() for y in x]
random.shuffle(name_list)
number = list(range(10000,10021))
random.shuffle(number)
dict1 = {'name':name_list,'number':number}
df1 = pd.DataFrame(dict1)
#2.求出滿足條件的數(shù)據(jù)
df1 = df1.set_index('name')
df2 = df1.groupby('name').count()
df1.loc[df2[df2.number>=5].index.tolist(),:]
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容