模块导入
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from scipy.stats import spearmanr
(L1) 将Excel工作簿 “Test.xlsx” 作为dataframe导入 Jupyter Notebook,并将dataframe命名为a
a=pd.read_excel('Test.xlsx')
a
(L2) dataframe a 中, class1-class5 指总共5门课,每个学生选两门,列出期中(midterm)、期末(final)成绩(A/B/C)。请用Python语言处理表格,将class1-class5列去除,并增加 class 和 grade 两列,使新dataframe的值与原dataframe对应,并将新dataframe命名为b.
第1种方法
b=pd.melt(a,id_vars=['name','test'],value_vars=['class1','class2','class3','class4','class5'],var_name='class',value_name='grade')
b=b[b['grade'].notnull()]
b
第2种方法
b1=a.set_index(['name','test']).stack().reset_index()
b1.rename(columns={'level_2':'class',0:'grade'},inplace=True)
b1
个人认为第2种方法简单。
(L3)用Python语言将dataframe b 的test列分成midterm和final两列,这两列的值是选的两门课的成绩。将新dataframe命名为c。
第1种方法
c=pd.pivot_table(b,values='grade',index=['name','class'],columns='test',aggfunc='max')
c
第2种方法
c1=b1.set_index(['name','class','test']).unstack()
c1
个人认为第2种方法简单。
(L4)如下为dataframe d 和 dataframe e,请用Python语言将dataframe d 和 dataframe e 匹配
d=pd.DataFrame({'fruit':['apple','banana','orange']*3,
'weight':['high','medium','low']*3,
'price':np.random.randint(0,15,9)})
e=pd.DataFrame({'pazham':['apple','orange','pine']*2,
'kilo':['high','low']*3,
'price':np.random.randint(0,15,6)})
d
e
de=pd.merge(d,e,left_on=['fruit','weight'],right_on=['pazham','kilo']).drop(columns=['pazham','kilo'],axis=1).rename(columns={'price_x':'price_left','price_y':'price_right'})
de
(L5)如下是 dataframe f,请用python语言得出每节课(class)和每个年级 (grade) 下, 学生的数量和平均成绩。
f=pd.DataFrame(['Sally','David','Jon','Jon'],columns=['name'])
f['score']=[95,99,80,83]
f['class']=['A','A','A','B']
f['grade']=['grade 1','grade 2','grade 1','grade 2']
f
f1=f.groupby(['class','grade']).agg({'name':'count','score':'mean'}).rename(columns={'name':'name count','score':'score mean'})
(L6) 如下是dataframe h,请用Python语言得出每行最小值除以每行最大值的商。
h=pd.DataFrame(np.random.randint(0,100,80).reshape(8,-1))
h
min_by_max=h.apply(lambda x:x.min()/x.max(),axis=1)
min_by_max
(L7) 如下是dataframe i,请用Python语言将dataframe i 里Min. Price 列中的NaN值替换成Min. Price 列的平均值, 并将 Max.Price 列中的NaN值替换成Max.Price列的中位数。
i=pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/Cars93_miss.csv')
i
方法1
i.loc[i['Min.Price'].isnull(),'Min.Price']=i['Min.Price'].mean()
i.loc[i['Max.Price'].isnull(),'Max.Price']=i['Max.Price'].median()
i
方法2
i['Min.Price'].fillna(i['Min.Price'].mean(),inplace=True)
i['Max.Price'].fillna(i['Max.Price'].median(),inplace=True)
i
方法1和方法2按个人习惯,得出的答案一样。
(L8)以dataframe形式读取 “mtcars.csv” , 并将dataframe命名为mtcars. 请分析每加仑英里数与哪些因子最相关?
mtcars=pd.read_csv('mtcars.csv')
mtcars
连续变量
num_list=list(mtcars.columns[2:8])+list(mtcars.columns[10:])
corrcoef={} # 存放列名与对应相关系数
for i in num_list:
coef,p=spearmanr(mtcars['mpg'],mtcars[i])
α=0.05
if p > α: # 95置信区间
print('{}和mpg不存在显著相关性')
else:
print(i+'和mpg存在显著相关性:p=%.3f'%(p))
sig_dic[i]=coef
corrcoef
连续型变量中,所有变量与msg存在显著相关性。其中drat,qsec,gear存在正相关,其余负相关。从相关系数绝对值来看,cyl,disp,hp,wt相关系数最高。
离散变量(vs,am)
mtcars_vs_0=mtcars[mtcars['vs']==0]['mpg']
mtcars_vs_1=mtcars[mtcars['vs']==1]['mpg']
mtcars_am_0=mtcars[mtcars['am']==0]['mpg']
mtcars_am_1=mtcars[mtcars['am']==1]['mpg']
list=[mtcars_vs_0,mtcars_vs_1]
colors=['#1b9e77','#d95f02']
box_plot=plt.boxplot(list,labels=['vs=0','vs=1'],widths=0.35,patch_artist=True,sym='o',whis=1.6)
for patch,color in zip(box_plot['boxes'],colors):
patch.set_facecolor(color)
plt.ylabel('mpg')
plt.grid(axis='y',color='gray',alpha=0.4,ls=':',lw=1) # 设置网格线
list=[mtcars_am_0,mtcars_am_1]
colors=['#1b9e77','#d95f02']
box_plot=plt.boxplot(list,labels=['am=0','am=1'],widths=0.35,patch_artist=True,sym='o',whis=1.6)
for patch,color in zip(box_plot['boxes'],colors):
patch.set_facecolor(color)
plt.ylabel('mpg')
plt.grid(axis='y',color='gray',alpha=0.4,ls=':',lw=1) # 设置网格线
从箱线图可以看出,不同vs/am取值对mpg存在显著性差异。
(L9)如下是某零售公司销售数据,假设样本够大,请根据数据分析,给出销售建议。
sales=pd.read_excel('Sales Data.xlsx')
sales
观察男女分组后的总收入和销售额
sales1=sales.groupby('性别')[['收入','销售额']].sum()
sales1['销售额/收入']=sales1['销售额']/sales1['收入']
sales1
从上述数据来看,男生的比例比女生高;指标 销售额/收入 越高越好,所以建议招男生数量要相对多一点。
观察年龄分组后的总收入和销售额
bins=[25,30,35,40,45]
sales['年龄分组']=pd.cut(sales['年龄'],bins=bins,labels=['26-30','31-35','36-40','41-45'])
sales2=sales.groupby(['年龄分组'])[['收入','销售额']].sum()
sales2['销售额/收入']=sales2['销售额']/sales2['收入']
sales2
从年龄分组来看,建议多招收年龄在26-35岁之间的人。
散点图
plt.rcParams['font.sans-serif']=['SimHei'] # 正常显示中文标签
plt.rcParams['axes.unicode_minus']=False
plt.scatter(sales['销售额'],sales['收入'])
plt.xlabel('销售额')
plt.ylabel('收入')
sales[sales['销售额']<130]
上述销售人员需重点关注,这部分销售人员的销售额很低,但是收入很高,应采取相应的管理办法(比如开除低销售高收入人员),减少公司的人力成本,提高公司的销售额。
(L10)如下为iris dataframe (未截全): 通过分析iris数据集中,判断 花萼长度为6,花萼宽度3,花瓣长度4,花瓣宽度2的花最可能是什么品种?
见我写的机器学习_鸢尾花数据集
链接:https://www.jianshu.com/p/9fc15d812b77
(L11)有5个卖家,每个卖家分别售卖5个商品;每个卖家对应的商品编号如下表: 请用R/python语言模拟如下随机过程:买手1,买手2,…买手150 分别在每个卖家随机购买一个商品;并满足如下条件:每种商品被购买次数不超过34次。
x=pd.DataFrame(np.arange(1,26).reshape(5,5),columns=['商品编号1','商品编号2','商品编号3','商品编号4','商品编号5'])
x['卖家号']=['A','B','C','D','E']
x=x[['卖家号','商品编号1','商品编号2','商品编号3','商品编号4','商品编号5']] # 顺序
x
from collections import Counter
customer_id=[]
goods_A=[]
goods_B=[]
goods_C=[]
goods_D=[]
goods_E=[]
goods={0:goods_A,1:goods_B,2:goods_C,3:goods_D,4:goods_E}
for i in range(150):
for j1,j2 in goods.items():
while True:
a=choice(x.iloc[j1,1:])
j2.append(a)
if max(Counter(j2).values())>34:
j2.remove(a)
continue
else:
break
customer_id.append(i)
x1=pd.DataFrame()
x1['买手编号']=customer_id
x1['购买商品编号1']=goods_A
x1['购买商品编号2']=goods_B
x1['购买商品编号3']=goods_C
x1['购买商品编号4']=goods_D
x1['购买商品编号5']=goods_E
x1
来检验下每种商品购买次数
x1['购买商品编号1'].value_counts()
x1['购买商品编号2'].value_counts()
x1['购买商品编号3'].value_counts()
x1['购买商品编号4'].value_counts()
x1['购买商品编号5'].value_counts()
由上可以看出每种商品购买次数<=34。