python清洗数据 food ounces animal_pandas基本操作

I

Int64Index: 150 entries, 0 to 149

Data columns (total 5 columns):

sepal length 150 non-null float64

sepal width 150 non-null float64

petal length 150 non-null float64

petal width 150 non-null float64

Iris class 150 non-null object

dtypes: float64(4), object(1)

memory usage: 7.0+ KB

None

df.describe():查看数值型列的汇总统计(数据总数、平均值、标准差、最小值、最大值、排序后位于25%的值、位于50%的值(中位数)以及位于75%的值),例子如下:

sepal length sepal width petal length petal width

count 150.000000 150.000000 150.000000 150.000000

mean 5.843333 3.057333 3.758000 1.199333

std 0.828066 0.435866 1.765298 0.762238

min 4.300000 2.000000 1.000000 0.100000

25% 5.100000 2.800000 1.600000 0.300000

50% 5.800000 3.000000 4.350000 1.300000

75% 6.400000 3.300000 5.100000 1.800000

max 7.900000 4.400000 6.900000 2.500000

也可以单独查看某项统计

df.count() :返回每一列非空值的个数

df.sum() :返回每一列的总和

df.min() :返回每一列的最小值

df.max():返回每一列的最大值

df.mean():返回每一列的平均值

df.median():返回每一列的中位数

df.std():返回每一列的标准差

df.corr():  列与列之间的相关系数

df.idxmin():???

df.idxmax():???

也可以单独查看某一列的sun、min、max、mean、median,语法如下:

df['B'].sum():查看B列所有数据的总和,其余类似

df.dtypes:查看每一列数据的数据类型

df[‘B’].dtype :查看列名为B的这列数据的数据类型

df.isnull() :判断每个数据是否为空值,返回的是df原数据换成True或False后的矩阵结果

df['B'].isnull():判断B列每个数据是否为空,返回的是B列数据换成True或False后的Series

df['B'].unique() :B列数据去重后的结果,有些网站上说的是查看B列唯一值,本人实际运行后发现是获取所有数据去重后的值

4、数据排序

df1 = df.sort_index(axis=1, ascending=False)  # df1为df按列名降序排列后的数据

df1 = df.sort_values(by='B')  # df1为df按照列B的值升序排序后的结果数据

5、数据选取

df[col]  根据列名,并以Series的形式返回数据

df[[col1, col2]]:以DataFrame形式返回多列,注意是两个综括号

另外可以通过loc、iloc选择数据。

首先创建一个DataFrame:

test_dict = {'id':[1,2,3,4,5,6],'name':['Alice','Bob','Cindy','Eric','Helen','Grace'],'math':[90,89,99,78,97,93]}

df = pd.DataFrame(test_dict,index=['a','b','c','d','e','f'])

增加一列:

df.insert(3,'english',[89,94,80,94,94,90])    //列索引从0开始,这里增加第4列,索引所在位置为3,列名为english,值为[89,94,80,94,94,90]。直接在原DataFrame上增加

df['english'] = [89,94,80,94,94,90]  //DataFrame中增加english列

增加一行:

df.loc['g'] = [7,'Iric',99,85]     //行索引g如果存在则更新,不存在则新增

删除数据:drop函数用于删除数据,label参数为要删除的数据,默认是行,如果要删除列,可以设置axis=1,axis默认为0表示行;如果不用label,使用index和columns参数可以删除行和列,看下面具体例子。

删除一列:

df1 =  df.drop(columns='english')   //drop并不改动原来的DataFrame,而是生成新的DataFrame

df1 = df.drop(['english'],axis=1)   //作用与上面等价

删除一行:

df1 = df.drop(index='f')   //删除索引为f的行,原DataFrame不动,生成新的DataFrame

df1 = df.drop(['a','f'])     //删除行索引为a,f的行

drop方法默认不在DataFrame本身进行操作,要想在本身进行操作,需要加上inplace=True参数,等价于操作完再赋值给本身,即df = df.drop(columns='english') 等价于df.drop(columns='english',inplace=True)

loc函数:基于索引标签值选择数据

df.loc['c']     //取行索引为c的那一行的数据

df.loc[['a','d','f']]   //取行索引为a,d,f的那三行数据

df.loc['b':'e']      //取行索引为b到e的数据,包含b和e行

df.loc['b','english']    //取行索引为'b',列名为english的那个数据。

df.loc[df['id']>2,'name']   //取id大于2的name列的数据

df.loc['c',['id','name']]   //取行索引为c的那一行对应的id和name两列的数据

df.loc['a':'c','name':'english']   //取行索引为a到c行,列名从name到english的所有数据

df.loc[:,'name']   //取name列的所有行

iloc函数:基于数字选择数据,行、列均从0开始

df.iloc[2]     //取行下标为2的那一行的数据(是我们看到的第三行,下标从0开始)

df.iloc[[0,3,5]]  //取行下标为0,3,5的那三行数据,即我们看到的第一行、第四行、第六行

df.iloc[3:5]    //取行下标为3到5(不包含5)的数据,即我们看到的第四、第五行

df.iloc[2,3]    //取行下标为2,列下标为3的那个数据

df.iloc[2,[0,1]]   //取行下标为2,列下标为0、1的数据,即行索引为c,列名为id,name的数据

df.iloc[0:2,1:3]   //取行下标为0到2但不包含2,列下标为1到3但不包含3的数据,即行索引为a、b,列索引为name、math的所有数据

df.iloc[:,1]   //提取name列的所有行

df.iloc[lambda x: x.index % 2 == 0]   //这里DataFrame的index要是数字,即上面例子中的abcdef索引换成012345,该行代码结果就是取索引为0,2,4的三行数据

at:用来选择单个值的,用法类似于loc

df.at['a','english']    //等价于df.loc['a','english']

iat:也是用来选择单个值,只是输入的参数是索引坐在的行号,类似iloc

df.iat[0,3]    //选择的值与df.at['a','english'] 一样

综上:

1)loc和iloc函数都是用来选择某行的,iloc与loc的不同是:iloc是按照行索引所在的位置来选取数据,参数只能是整数,从0开始计数。而loc是按照索引名称来选取数据,参数类型依索引类型而定;

2)at和iat函数是只能选择某个位置的值,iat是按照行索引和列索引的位置来选取数据的,同iloc一样,从0开始计数。而at是按照行索引和列索引名称来选取数据;

3)loc和iloc函数的功能包含at和iat函数的功能

4)另外iloc与loc不同的一点是切片范围,iloc不包含范围的结束下标,例如0:3,df.loc['a':'d']选择的是a、b、c、d四行,而df.iloc[0:3]选择的是0、1、2三行。

6、数据清洗

填充空值:

df.fillna(value=0)   //用0填充整个DataFrame的NaN值

df.fillna(df['math'].mean())   //用math列的均值填充整个DataFrame的NaN值

df['math'].fillna(df['math'].mean())   //用math列的均值填充math列的NaN值

fillna函数默认不在DataFrame本身进行操作,要想得到填充后的数据,要么自己赋值(df = df.fillna(0)  df['math'] = df['math'].fillna(df['math'].mean())),要么在fillna函数中设置inplace=True

去除空格:

df['name'].str.strip  //只能去掉字符串首尾的空格,中间的不会去掉

df['name'] = df['name'].map(str.strip)  //效果同上,上面的返回结果数据类型是,如果直接赋值给name列,那么name列所有数据变成>,利用map函数转换则返回数据类型是Series,重新赋值给name列

大小写转换:

df['name'] = df['name'].map(str.lower) //全部小写,加map的道理同上

df['name'] = df['name'].map(str.upper) //全部大写

df['name'] = df['name'].map(str.capitalize)  //首字母大写,其余小写

//python对字符串的处理函数中,不需要传入参数的都可以放到map里写成str.method

map可以根据数组、Series或者DataFrame列中的值来实现转换,下面给出一个例子:

data = pd.DataFrame({'food':['bacon','pulled pork','bacon','Pastrami'], 'ounces':[4,3,12,6]})

meat_to_animal = {'bacon':'pig','pulled pork':'pig','pastrami':'cow'}

#Series的map方法接受一个函数或含有映射关系的字典对象,对元素进行相应的转换

data['animal']=data['food'].map(str.lower).map(meat_to_animal)

data

food ounces animal

0 bacon 4.0 pig

1 pulled pork 3.0 pig

2 bacon 12.0 pig

3 Pastrami 6.0 cow

data['animal1'] = data['food'].map(lambda x: meat_to_animal[x.lower()])//作用与上面等价

data

food ounces animal animal1

0 bacon 4.0 pig pig

1 pulled pork 3.0 pig pig

2 bacon 12.0 pig pig

3 Pastrami 6.0 cow cow

更改数据格式:

df['math'] = df['math'].astype('int')  //假设原来math列为float类型,更改为int类型时,小数部分直接去掉,不进行四舍五入

更改列名:

df.rename(columns={'sepal_length':'length'},inplace=True)  //sepal_length更改为length,inplace=True设置更改作用在原DataFrame上,否则原DataFrame不会改变

替换某列的值:

df['name'] = df['name'].replace('Iris-setosa','yy')  //将name列值为Iris-setosa的数据用yy替换,不用等号赋值也可以在replace中设置inplace=True

删除后出现的重复的值:

df['name']=df['name'].drop_duplicates() //drop_duplicates()将name列中的重复元素删除,保留最先出现的一个,将删除后返回的数据再赋值给name列时,原来重复的位置数据为NaN

删除先出现的重复的值:

df['name']=df['name'].drop_duplicates(keep='last') //同上,相当于将name列最先出现的重复值设置为NaN

整个DataFrame删除某列重复的数据:

df.drop_duplicates(['math'],inplace=True) //删除math列后出现的重复值对应的记录

df=df.drop_duplicates(['math','english']) //删除math和english两列同时重复的后出现的记录,keep='last'参数作用同上

7、多表处理

1)merge合并

df1 = pd.DataFrame(

{"id":[1001,1002,1003,1004,1005,1006],

"date":pd.date_range('20130102', periods=6),

"city":['Beijing', 'SH', ' guangzhou ', 'Shenzhen', 'shanghai', 'BEIJING '],

"age":[23,44,54,32,34,32],

"indextest":['a','b','c','d','e','f'],

"price":[1200,np.nan,2133,5433,np.nan,4432]},

columns =['id','date','city','category','age','price'])

df2 = pd.DataFrame(

{"id":[1001,1002,1003,1004,1005,1006,1007,1008],

"gender":['male','female','male','female','male','female','male','female'],

##"city":['Beijing', 'SH', 'GZ', 'SZ', 'SH', 'BJ'],

"pay":['Y','N','Y','Y','N','Y','N','Y',]},

index=['a','c','d','e','f','g','h','i']

)

pd.merge(df1,df2)   //将df1、df2以join方式合并,自动查找列名相同的进行join

pd.merge(df1,df2,on='id',how='left')   //相当于sql的df1 left join df2 on df1.id = df2.id。on参数指定关联的列名,必须是两个DataFrame都有的;how参数指定关联的方式,默认为join,另外还有left、right、outer

pd.merge(df1,df2,left_on='id',right_on='idd')  //df1 join df2 on df1.id = df2.idd。当df1和df2中没有相同的列索引名时,不能使用on,需要指定两边进行关联的列名,通过left_on、right_on参数指定

pd.merge(df1,df2,on=['id','city'],how='outer')  //根据id和city两个列名进行合并

pd.merge(df1t,df2,on='id',suffixes=('_left','_right'))  //df1和df2有两个相同的列名id和city,当只用id做合并关联字段时,city就是重复的,通过suffixed参数指定重复列名合并后的新名称,左边的表在原名称基础上加上‘_left’,右边的表在原名称基础上加上‘_right’,最终合并后的列名为id,date,city_left,age,category,price,gender,city_right,pay

pd.merge(df1,df2,left_on='indextest',right_index=True)  //df1的indextest列与df2的行索引即index进行关联合并。当需要左表使用行索引进行关联时,设置left_index=True。

复合行索引与多列进行关联,例如:

lefth = pd.DataFrame({'key1':['Ohio','Ohio','Ohio','Nevada','Nevada'],

'key2':[2000,2001,2002,2001,2002],

'data':np.arange(5.0)})

righth = pd.DataFrame(np.arange(12).reshape((6,2)),

index=[['Nevada','Nevada','Ohio','Ohio','Ohio','Ohio'],

[2001,2000,2000,2000,2001,2002]],

columns=['event1','event2'])

pd.merge(lefth,righth,left_on=['key1','key2'],right_index=True)

结果如下:

key1key2dataevent1event2        0Ohio20000.045        0Ohio20000.067        1Ohio20011.089        2Ohio20022.01011        3Nevada20013.001

2)join合并(单纯使用索引进行合并)例子如下:

left2 = pd.DataFrame([[1.0,2.0],[3.0,4.0],[5.0,6.0]],index = ['a','c','e'],columns=['Ohio','Nevada'])

right2 = pd.DataFrame([[7.0,8.0],[9.0,10.0],[11.0,12.0],[13.0,14.0]],index = ['b','c','d','e'],columns=['Missouri','Alabama'])

left2.join(right2)

OhioNevadaMissouriAlabama        a1.02.0NaNNaN        c3.04.09.010.0        e5.06.013.014.0

3)append合并:

将一个表的数据追加到另一个表中,两个表的列名必须相同

df1 = pd.DataFrame([[1, 2], [3, 4]], columns=list('AB'))

A  B

0  1  2

1  3  4

df2 = pd.DataFrame([[5, 6], [7, 8]], columns=list('AB'))

df1.append(df2)

A  B

0  1  2

1  3  4

0  5  6

1  7  8

df1.append(df2, ignore_index=True)

A  B

0  1  2

1  3  4

2  5  6

3  7  8

注意,append函数是生成新的DataFrame,并不会影响原来的DataFrame,所以需要赋值才能让原变量获取合并后的数据(上面例子df1并没有变化)。

df1 = df1.append({'A':8,'B':8},ignore_index=True)     查看df1结果如下:

A  B

0  1  2

1  3  4

2  8  8

4)轴向链接concat

轴向链接是指根据某个轴向来拼接数据,pandas中索引列(纵轴)为0,列名(横轴)行为1,concat函数默认在0轴上工作,即axis参数默认为0。concat可以作用于Series和DataFrame,下面看例子。

在0轴拼接:

s1 = pd.Series([0,1],index=['a','b'])

s2 = pd.Series([2,3,4],index=['c','d','e'])

s3 = pd.Series([5,6],index=['f','g'])

pd.concat([s1,s2,s3])

#输出

a    0

b    1

c    2

d    3

e    4

f    5

g    6

dtype: int64

在1轴拼接:

pd.concat([s1,s2,s3],axis=1)

#输出

0    1    2

a  0.0  NaN  NaN

b  1.0  NaN  NaN

c  NaN  2.0  NaN

d  NaN  3.0  NaN

e  NaN  4.0  NaN

f  NaN  NaN  5.0

g  NaN  NaN  6.0

在上面的情况下,参与连接的片段在结果中区分不开,假设你想要在连接轴上创建一个层次化索引,我们可以额使用keys参数:

result = pd.concat([s1,s1,s3],keys=['one','two','three'])

result

#输出

one    a    0

b    1

two    a    0

b    1

three  f    5

g    6

dtype: int64

result = pd.concat([s1,s1,s3],keys=['one','two','three'],axis=1)

#输出

one  two  three

a  0.0  0.0    NaN

b  1.0  1.0    NaN

f  NaN  NaN    5.0

g  NaN  NaN    6.0

8、离散化数据

在数据分析中,有些数据需要归类到几个大类中,比如根据年龄将人划分为少年,青年,壮年,老年,可以用cut函数实现,具体用法如下,这里只介绍关键的参数。

df = pd.DataFrame({'name':['luci','jack','bob'],'age':[20,5,45]})

df['age_s']=pd.cut(df['age'],[0,15,30,60,100],labels=False)

df

name  age  age_s

0  luci   20      1

1  jack    5      0

2   bob   45      2

cut中第一个参数是需要进行划分范围的数据,第二个参数是范围,像上面例子中的[0,15,30,60,100]是划分了4个范围,对应的code为0,1,2,3,labels的False设定不显示范围值,用code代替,也可以设置labels为你需要的值,例如labels=['少年','青年','壮年','老年'],如果不设置labels参数,则显示的是范围值,如下所示

ct = pd.cut(df['age'],[0,15,30,60,100])

0    (15, 30]

1     (0, 15]

2    (30, 60]

Name: age, dtype: category

Categories (4, interval[int64]): [(0, 15] < (15, 30] < (30, 60] < (60, 100]]

第二个参数也可以是一个整数,例如我们希望分4段,参数值为4时,pandas会根据所有的值自动划分,如下所示,pandas自动划分成了(4.96, 15.0] 、 (15.0, 25.0] 、 (25.0, 35.0]

ct = pd.cut(df['age'],4)

0    (15.0, 25.0]

1    (4.96, 15.0]

2    (35.0, 45.0]

Name: age, dtype: category

Categories (4, interval[float64]): [(4.96, 15.0] < (15.0, 25.0] < (25.0, 35.0] < (35.0, 45.0]]

分享到:

18e900b8666ce6f233d25ec02f95ee59.png

72dd548719f0ace4d5f9bca64e1d7715.png

2019-11-22 15:08

浏览 64

评论

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值