pandas数据处理
删除重复元素
#删除一行或一列 #dropna() 删除空值 #drop_duplicates() 删除重复的行 import numpy as np import pandas as pd from pandas import Series,DataFrame data = np.random.randint(0,150,size=(5,5)) index = list('ABCDE') columns = list('甲乙丙丁戊') df = DataFrame(data=data, index=index, columns=columns) dfdf.loc['A'] = [100,100,100,100,100] df.loc['C'] = [100,100,100,100,100] df.loc['E'] = [100,100,100,100,100] df #查看重复的行 temp = df.duplicated(keep='last') display(df,temp) df[temp].index df.drop(df[temp].index,axis=0)#使用duplicated函数查看重复的行 #使用drop_duplicates()函数删除重复的行 df.drop_duplicates(keep='last') #如果使用pd.concat([df1,df2],axis=1)生成的DataFrame,新的df中 #columns相同,使用duplicate()和drop_duplicates()就会有问题 映射
映射的含义:创建一个映射关系列表,把values元素和一个特定的标签或字符串绑定
# replace()函数 替换元素 # map()函数 新建一列 # rename()函数 替换索引 s1 = Series(data=np.array(['dancer',1,None,3,'北京']),dtype=str) s1 #普通替换 s1.replace(to_replace='dancer',value='DANCER') #多值替换 s1.replace(to_replace=['dancer','北京'],value=['DANCER','首都']) #注意:替换空值要使用中括号,不然会理解为参数是没有的 s1.replace(to_replace=[None],value='没有值') s1[3] = 'dancer' s2 = s1.replace({'dancer':'DANCER'}) s2[1] = 'DANCER' s2[2] = 'DANCER'DataFrame 替换操作
data = np.random.randint(0,150,size=(5,5)) df = DataFrame(data=data) df.columns = list('ABCDE') df.loc[0,'E'] = 'dancer' df.loc[1,'D'] = 'dancer' df df.replace({'D':'dancer'},'DANCER') #map() 新建一列 data = np.random.randint(0,100,size=(5,5)) index = list('ABCDE') columns = list('甲乙丙丁戊') df = DataFrame(data=data,index=index,columns=columns) df['甲'] = ['dancer','lucy','lili','tom','jack'] df['申'] = [100,90,80,20,100] map_dic = { 'dancer':'男', 'lucy':'女', 'lili':'女', 'tom':'男', 'jack':'男' } df['性别'] = df['甲'].map(map_dic) def transform_score(item): if item > 90: return 'A' elif item > 80: return 'B' elif item > 70: return 'C' elif item > 60: return 'D' else: return 'E' #将这一列的分数映射成 ABCDE 5分制成绩 df['分数'] = df['乙'].map(transform_score) df df['庚'] = df['戊'].map(lambda x : x/2 +50) #map() 可以映射新的一列数据 #map() 中可以使用lambda表达式 #map() 可以使用函数,也可以是自定义的函数 #map() 不能使用sum之类的函数,for循环 #map() 字典的键要足以匹配所有的数据,否则出现NaN # transform()参数只能是函数,不能是字典 df['乙'].transform(transform_score)rename()函数:替换索引
data = np.random.randint(0,150,size=(5,5)) columns = ['python','java','c','php','c#'] index = ['lucy','mery','jack','tom','rose'] df = DataFrame(data=data,columns=columns,index=index) df.rename(index={'jack':'wuqilong'}) df.rename(columns={'python':'最好的语言','php':'还行'}) score = pd.concat((df,df),axis=1,keys=['上学期','下学期']) #使用rename()函数替换行索引 # map 替换所有索引 # index 替换行索引 # columns 替换列索引使用聚合操作对数据异常值检测和过滤
#describe()可以查看每一辆描述性统计量 score.describe() #std()函数可以求得df对象每列的标准差 score.std(axis=1) #根据每列或每行的标准差,对df元素进行过滤 #借助any()或all()函数,测试是否有True #对每列应用筛选条件,去除标准差太大的数据 df = DataFrame(data=np.random.randn(10000,3),columns=list('ABC')) df drop_labels = df[(np.abs(df) > 3*df.std()).any(axis=1)].index df.drop(drop_labels,inplace=True) df.shape排序
# 使用take()函数排序 # 可以借用np.random.permutation()函数随机排序 data = np.random.randint(0,100,size=(5,5)) index = list('ABCDE') columns = list('甲乙丙丁戊') df = DataFrame(data=data,index=index,columns=columns) df df.take([2,1,4]) sort_random = np.random.permutation(5) df.take(sort_random,axis=0) 随机抽样
#当DataFrame规模足够大,可以直接使用np.random.randint(), #配合take()函数实现随机抽样 data = np.random.randn(10000,3) df = DataFrame(data=data) df df.take(np.random.randint(0,10000,size=5)) 数据分类处理
#数据的聚合是数据处理的最后一步,通常情况下使每一个数组生成一个单一的数值 #数据分类处理: # 分组:先把数据分为几组 # 用函数处理:为不同组的数据应用不同的函数以便转化数据 # 合并:把不同组得到的结果数据合并起来 #数据分类处理的函数: # groupby() 函数 # groups属性 可以查看分组的情况 df = DataFrame({ 'item':['苹果','香蕉','橘子','香蕉','橘子','苹果'], 'price':[4,3,3,2,2.5,4], 'color':['red','yellow','yellow','green','green','green'], 'weight':[12,20,50,30,20,44] }) df df.groupby('item').sum()['weight'] df.groupby('color').mean()['price'] df.groupby(['color','item']).mean()['price'] df.groupby('price').groups df.groupby('item').groups total = df.groupby('item')['weight'].sum() total = DataFrame(total) total.reset_index(inplace=True) total result = pd.merge(df,total,on='item',suffixes=['','_total']).rename(columns={ 'weight_total':'total'}) result """ 练习:假设菜市场张大妈在卖菜,有以下属性: 菜品(item):萝卜,白菜,辣椒,冬瓜 颜色(color):白色,青色,红色 重量(weight) 价格(price) 1.以属性为列索引,创建一个DataFrame对象df 2.对df进行聚合操作,求出颜色为白色的价格总和 3.对df进行聚合操作,求出各菜品的所有重量以及平均价格 4.使用merge合并总重量及其平均价格 """data = { 'item':['萝卜','萝卜','白菜','辣椒','白菜','辣椒','冬瓜','萝卜'], 'color':['white','red','white','red','green','green','green','green'], 'price':[2,1.5,2,1,4,3,5,8], 'weight':[100,50,30,20,40,50,60,40] } df = DataFrame(data=data) df df.groupby('color')['price'].sum().loc['white'] total_weight = DataFrame(df.groupby('item')['weight'].sum()) total_weight def my_mean(items): m = 0 for item in items: m += item return m/len(items) mean_price = DataFrame(df.groupby('item')['price'].apply(my_mean)) table1 = pd.merge(df,mean_price,left_on='item',right_index=True, suffixes=['','_mean']).rename(columns={ 'price_mean':'mean'}) table2 = pd.merge(table1,total_weight,left_on='item', right_index=True,suffixes=['','_sum']).rename(columns={ 'weight_sum':'total' }) 高级数据聚合
#除了使用groupby分组后,我们也可以使用transform和apply提供 #实现自定义函数更多的运算 #传入一个数组 def my_sum(items): s = 0 for item in items: s += item return s df.groupby('item')['price'].sum() df.groupby('item')['price'].apply(my_sum) df.groupby('item')['price'].mean() mean_price = DataFrame(df.groupby('item')['price'].apply(my_mean)) pd.merge(df,mean_price,left_on='item',right_index=True) def my_test(items): s = 0 for i in items: s += i return s mean_p = DataFrame(df.groupby('item')['price'].transform(my_test)) mean_p.columns = ['mean'] pd.concat((df,mean_p),axis=1)