以题代学—pandas数据处理速成

问题1 计算涨幅

  • 题目描述
    一个 df 有三个列需要进行计算,change_type 值 为1和0, 1为涨价,0为降价, price为现价, changed为涨降价的绝对值, 现求:涨降价的比例, 精确到0位,无小数位。
  • 知识点提要
    (1)apply + lambda函数
    (2)map + format
    (3)区分apply和map
    传送门:pandas常用知识点
  • 解法
#1.构造数据
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]})
#通过字典创建dataframe
#2.编写函数
#第一个函数计算涨幅
#第二个函数转换为要求格式的百分比
func1 = lambda x: x['changed']/x['price'] if x['change_type'] == 1 else -x['changed']/x['price']
#注意1,结合apply时候设置axis=1参数,否则报错。
#注意2,pandas结合lambda函数可以针对整个df进行操作。
func2 = lambda x: format(x,'.0%')
#注意格式处理的方法,有两种一种是%占位符,一种是format,个人认为现用现百度。
#3.计算
df['percentage'] = df.apply(func1,axis=1).map(lambda x:format(x,'.0%'))

问题2 同一个dataframe里根据某列值更改另一列的值

  • 题目描述
    有一个dataframe存储了两列数据,一列点评ID,一列点评状态,要求点评ID为null的点评状态赋值为0,点评ID不为null的赋值为1。
  • 知识点提要
    (1)apply+自定义函数(def)
    (2)loc + 数据框赋值 + ~用法
  • 解法
#1.构造数据
df = pd.DataFrame(
    {"has_comment_or_not":['0','0','0','1','0','0'],
    "comment_status":["null","null","120047007","null","null","122121"]}
    )
#2.解法1:编写函数求解
##2.1 编写传统函数
def change_status(s):
    if s.comment_status == 'null':
        return 0
    else:
        return 1
#这种做法更适合复杂的业务场景,用编写函数的形式做一套流程化的东西,s就可以认为是数据框,再apply的时候设置axis=1。
##2.2应用函数
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,里边存储着蔬菜名和对应的大类别,要求按照df2的蔬菜名和大类别对应关系给df1的蔬菜名重新赋值。
    注意:如果df2中没有df1中的蔬菜名那么蔬菜1保留原值;
    如果df2中对应的大类别为空,那么df1中的蔬菜名保持原值;
    其他情况进行替换。
  • 知识点提要
    (1)map+字典
    (2)map+dataframe
  • 解法
#1.构造数据
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的两列转换为字典,直接转肯定是没有函数了,
#首先添加一个辅助列,把二者对应为字典,
#然后根据字典的特征,构造一个大字典。
#然后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结合使用,这里的df要设置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 销售数据的聚合统计

  • 题目描述:
    有一个tsv文件存储着某公司的销售数据,读入这个tsv,并对数据做以下统计:
    (1)统计下单最多的商品(item_name)
    (2)统计有多少种商品被下单
    (3)统计下单最多的商品(choice_description)
    (4)计算所有商品的总收入
    (5)统计订单数
    (6)统计所有订单的平均收入

  • 知识点提要
    (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]
#统计有多少种商品被下单
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转换为浮点数
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相当于没求,所以还是先增列再求和比较稳妥
#统计订单数
df6.order_id.nunique()
#统计所有订单的平均收入
round(df6.groupby('order_id').sum_revenue.sum().mean(),2)

问题5 统计每位学生平均分数最高的课程

  • 题目描述
    有一个数据框存储着学生的考试成绩,但考试成绩分为期中和期末两次,计算每一个同学的平均分。
  • 知识点提要
    (1)reset_index()
    (2)idxmax和iloc的使用
  • 解法
#1.创建数据框
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.计算平均分数
df7 = df6.groupby(['ID','cls']).score.mean().reset_index()
#3.找出最高分数的课程
df7.iloc[df7.groupby(['ID']).score.idxmax(),1:3]

问题6 数据框的转置

  • 题目
    这个问题是一道休闲题,算是这个系列到这的一个休息。问题有一个数据框,如何实现行和列的转置。
  • 知识点提要
    (1).T
    (2)stack和unstack
  • 解法
#1.构造数据
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也可以用转置这个很神奇
#2.2 stack解法
df2 = df1.stack()
df2 = df2.unstack(level=0)
#stack和unstack有个参数level主要是控制index的层次

问题7 缺失值的处理

  • 题目
    现在有一个数据框,里边由于数据存储操作问题,存在很多缺失值,要如何处理这些缺失值。缺失值处理包括的内容比较多,比如缺失值的统计,缺失值的删除,缺失值的填充等等。具体题目包括:
    (1)统计具有缺失值的列
    (2)统计每一列有几个缺失值
    (3)删除city列为空的数据
    (4)处理age列的缺失值
  • 知识点提要
    (1)isna()
    (2)any()
    (3)fillna()
  • 解法
#构造数据
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.统计有缺失值的列
df7.isna().any()
#2.统计每一列有几个缺失值
df7.isna().sum()
#3.删除city列为空的数据
df7.dropna(subset=['city'],how='any')
#4.数据变量缺失值的填充
df7['age'].fillna(df7['age'].mean(),inplace=True)
##这里需要注意的是如果是mode可能有很多个数,用个切片[0],把数据取出来

问题8 数据抽样

等我补充

问题9 计算文本的平均长度

  • 题目
    现在有一个数据框,存的数据包括id和text两列,现在要求平均文本你长度。
  • 知识点提要
    (1)lambda
    (2)mean
  • 解法
#1.构造数据
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个以上不同数据的所有数据

  • 题目
    现在有一个数据框,包括姓名和number两列数据,现在要求筛选出来具有五个以上number值的所有数据,注意筛选出来的数据要包括姓名和number的所有数据。
  • 知识点提要
    (1)set_index
    (2)dataframe切片
  • 解法
#1.构造数据
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.求出满足条件的数据
df1 = df1.set_index('name')
df2 = df1.groupby('name').count()
df1.loc[df2[df2.number>=5].index.tolist(),:]

你可能感兴趣的:(以题代学—pandas数据处理速成)