pandas基本操作
程序员文章站
2022-05-31 23:26:52
...
1、导入数据
pd.read_csv(filename):从CSV文件导入数据
pd.read_excel(filename):从Excel文件导入数据
pd.read_table(filename):从限定分隔符的文本文件导入数据
pd.read_sql(query, connection_object):从SQL表/库导入数据
pd.read_json(json_string):从JSON格式的字符串导入数据
pd.read_html(url):解析URL、字符串或者HTML文件,抽取其中的tables表格
pd.read_clipboard():从你的粘贴板获取内容,并传给read_table()
pd.DataFrame(dict):从字典对象导入数据,Key是列名,Value是数据
2、将数据保存到指定文档
pd.to_csv() //保存数据到csv文档
pd.to_excel() //保存数据到excel
3、常用的查看、检查数据函数
df.head(n):查看DataFrame对象的前n行
df.tail(n):查看DataFrame对象的最后n行
df.index 查看行名(有时为0、1、2、3...,可以看出有多少行数据)
df.columns 查看列名
df.values 查看矩阵,也就是实际数据
df.shape:查看行数和列数
df.info():查看索引、数据量、每列数据类型、是否存在空值、内存信息,例子如下
df.describe():查看数值型列的汇总统计(数据总数、平均值、标准差、最小值、最大值、排序后位于25%的值、位于50%的值(中位数)以及位于75%的值),例子如下:
也可以单独查看某项统计
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:
增加一列:
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) //效果同上,上面的返回结果数据类型是<class 'method'>,如果直接赋值给name列,那么name列所有数据变成<bound method StringMethods.strip of <pandas.core.strings.StringMethods object at 0x0000000DEF153908>>,利用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列中的值来实现转换,下面给出一个例子:
更改数据格式:
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)
结果如下:
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)
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] <、(35.0, 45.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]]
pd.read_csv(filename):从CSV文件导入数据
pd.read_excel(filename):从Excel文件导入数据
pd.read_table(filename):从限定分隔符的文本文件导入数据
pd.read_sql(query, connection_object):从SQL表/库导入数据
pd.read_json(json_string):从JSON格式的字符串导入数据
pd.read_html(url):解析URL、字符串或者HTML文件,抽取其中的tables表格
pd.read_clipboard():从你的粘贴板获取内容,并传给read_table()
pd.DataFrame(dict):从字典对象导入数据,Key是列名,Value是数据
2、将数据保存到指定文档
pd.to_csv() //保存数据到csv文档
pd.to_excel() //保存数据到excel
3、常用的查看、检查数据函数
df.head(n):查看DataFrame对象的前n行
df.tail(n):查看DataFrame对象的最后n行
df.index 查看行名(有时为0、1、2、3...,可以看出有多少行数据)
df.columns 查看列名
df.values 查看矩阵,也就是实际数据
df.shape:查看行数和列数
df.info():查看索引、数据量、每列数据类型、是否存在空值、内存信息,例子如下
I<class 'pandas.core.frame.DataFrame'> 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) //效果同上,上面的返回结果数据类型是<class 'method'>,如果直接赋值给name列,那么name列所有数据变成<bound method StringMethods.strip of <pandas.core.strings.StringMethods object at 0x0000000DEF153908>>,利用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)
结果如下:
key1 | key2 | data | event1 | event2 | 0 | Ohio | 2000 | 0.0 | 4 | 5 | 0 | Ohio | 2000 | 0.0 | 6 | 7 | 1 | Ohio | 2001 | 1.0 | 8 | 9 | 2 | Ohio | 2002 | 2.0 | 10 | 11 | 3 | Nevada | 2001 | 3.0 | 0 | 1 |
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)
Ohio | Nevada | Missouri | Alabama | a | 1.0 | 2.0 | NaN | NaN | c | 3.0 | 4.0 | 9.0 | 10.0 | e | 5.0 | 6.0 | 13.0 | 14.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] <、(35.0, 45.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]]
上一篇: python实现字符串反转的多种方法
下一篇: pandas基本操作