Python科学计算:Pandas

Python科学计算:Pandas

Pandas提供的数据结构DataFrame与json的锲合度很高,转换很方便

Series和DataFrame两个核心数据结构,分别代表一维的序列和二维的表结构,基于这两个数据结构,Pandas可以对数据进行导入等等

数据结构:Series 和 DataFrame

Series是个定长的字典序列,在存储的时候,相当于两个ndarray,这也是和字典结构最大的不同,因为在字典的结构里,元素的个数是不固定的

有两个基本属性,index 和 values,在series结构中,index默认是0,1,2,……递增的整数序列,也可以指定索引,比如index = [‘a’, ‘b’ , ‘c’]

import pandas as pd 
from pandas import Series , DataFrame
x1 = Series([1,2,3,4])
x1 = Series(data = [1,2,3,4], index = ['a' , ' b' , 'c' , 'd'])
print x1
print x2

0 1

1 2

2 3

3 4

dtype:int64

a 1

b 2

c 3

d 4

dtype:int64

x1中的index是默认值,x2的index进行了指定,前面是data (values),后面是index

或者可以用字典的方式来创建series:

d = {'a' :1,'b':2,'c':3,'d':4}
x3 = Series(d)
print x3

DataFrame 类型数据结构类似数据库表

包括行索引和列索引,可以将DataFrame看成是由相同索引的Series组成的字典类型

想输出几个同学的考试成绩:

import pandas as pd
from pandas import  Series,DataFrame
data = {'Chineses' :[66,96,93,90,80],'English':[75,65,85,88,90],'Math':[30,98,66,77,90]}
df1 = DataFrame(data)
df2 = DataFrame(data,index = ['Zhangfei','Guanyu','Zhaoyun','Huangzhong','Dianwei'],columns=['English','Math','Chineses'])
print df1
print df2

df2的列索引是[‘English’,‘Math’,‘Chineses’],行索引是 [‘Zhangfei’,‘Guanyu’,‘Zhaoyun’,‘Huangzhong’,‘Dianwei’],所以df2的输出是:

                                            English       Math     Chineses
Zhangfei                         75                  30         66
Guanyu                           65                  98         96
Zhaoyun                        85                  66          93
Huangzhong                88                 77           90
Dianwei                         90                 90             80

数据导入和输出

Pandas允许直接从xlsx ,csv中导入数据,也可以输出到xlsx, csv等文件中

import pandas as pd
from pandas import  Series,DataFrame
score = DataFrame(pd.read_excel('data.xlsx'))
score.to_excel('datal.xlsx')
print score

如果运行的过程中可能缺少xlrd 和 openpyxl包的情况,使用pip install安装

数据清洗

data = {'Chineses' :[66,96,93,90,80 ],'English':[75,65,85,88,90],'Math':[30,98,66,77,90]}
df2 = DataFrame(data,index= ['Zhangfei','Guanyu','Zhaoyun','Huangzhong','Dianwei'],columns=['English','Math','Chineses'])

清理过程中,一般遇到以下情况:

1.删除DataFrame中不必要的行和列

使用drop()函数来删除不必要的行或列,比如想把语文这列删除

df2 = df2.drop(columns=['Chineses'])

想把张飞这行删除

df2 = df2 . drop(index = ['Zhangfei'])
2.重命名列明columns,让列表名更容易识别

使用rename(columns = new_names , inplace = True)函数,比如把Chineses -> TuWen,English->YingYu

df2.rename(columns={'Chineses':'YuWen' , 'English':'YingYu' } , inplace = True)
3,去掉重复的值

drop_duplicates()自动去掉重复的行

df = df.drop_duplicates()  #去掉重复行

4. 格式问题

更改数据格式

很多时候数据格式不规范,使用astype函数规范格式,比如Chineses自动的值改成str类型,或者int64

df2['Chineses'].astype('str')
df2['Chineses'].astype(np.int64)
数据间的空格

先把格式转成了str类型是为了方便对数据进行操作,这时想删除数据间的空格,使用strip函数

#删除左右两边空格
df2['Chineses'] = df2['Chineses'].map(str.strip)
#删除左边的空格
df2['Chineses'] = df2['Chineses'].map(str.lstrip)
#删除右边的空格
df2['Chineses'] = df2['Chineses'].map(str.rstrip)

还可以使用strip函数删除某个特殊符号,如果Chineses字段中有美元符号

df2['Chineses'] = df2['Chineses'].str.strip('$')
大小写转换

人名、城市名等的统一可能用到大小写的转换,可以使用upper() , lower() , title()

#全部大写
df2.columns = df2.columns.str.upper()
#全部小写
df2.columns = df2.columns.str.lower()
#首字母大写
df2.columns = df2.columns.str.title()
查找空值

有些字段存在空值Nan的可能,用isnull函数查找

如果想看哪些地方存在空值NaN,可以针对数据表df进行df.isnull(),结果为True的就是空值

想知道那列存在空值,可以使用df.isnull().any(),结果为True的就是空值

使用apply函数对数据进行清洗

对name列的数值都进行大写转化:

df['name']  =  df['name'].apply(str.upper)

定义个函数,在apply中进行使用,定义double_df函数是将原来的数值*2进行返回,然后对df1中的’语文’列的数值进行*2处理:

def double_df(x):
	return 2*x
df1[u'语文'] = df1[u'语文'].apply(double_df)

可以定义更加复杂的函数,对于DataFrame,新增两列,其中’new1’列是‘语文’和‘英语’成绩之和的m倍,‘new2’列是‘语文’和‘英语’成绩之和的n倍

def plus(df,n,m):
	df['new1'] = (df[u'语文']+df[u'英语']) * m
	df['new2'] = (df[u'语文'] + df[u'英语']) * n 
	return df
df1 = df1.apply(plus,axis=1,args=(2,3,))

axis = 1 代表按照列为轴进行操作,axis= 0 代表按照行为轴进行操作,args是传递的两个参数,即n=2,m=3,在plus函数中使用了n 和m,从而生成新的df

数据统计

describe()函数,可以对数据有个全面的了解

df1 = DataFrame({'name' : ['Zhangfei' , 'Guanyu' , 'a' , 'b' , 'c'] , ' data1':range(5)})
print df1.describe()

count 5.000000

mean 2.000000

std 1.******

min 0.000000

25% 1.000000

50% 2.000000

75% 3.000000

max 4.000000

数据表合并

将多个渠道源的多个数据表进行合并

# 创建两个DataFrame
df1 = DataFrame({'name' :  ['Zhangfei' , 'Guanyu' , 'a' , 'b' , 'c'] , ' data1':range(5)})
df2 = DataFrame({'name' :  ['Zhangfei' , 'Guanyu' , 'A' , 'B' , 'C'] , ' data1':range(5)})
1. 基于指定列进行连接
#   基于name列进行连接
df3 = pd.merge(df1,df2,on = 'name')   //然后返回df1  和 df2 两个表中name列相同元素的部分
2.inner内连接
# inner内连接是merge合并的默认情况,inner内连接是键的交集,这里df1 & df2 相同的键是name,所以是基于name字段做的连接
df3 = pd.merge(df1,df2,how='inner')
3.left 左连接
# 左连接是以第一个 DataFrame为主进行的连接,第二个 DataFrame作为补充
df3 = pd.merge(df1, df2,how='left')   //返回的是先是data1 和name是第一个表的内容,还有data2除了相同的数值其他都是NaN

def3:

data1 name data2

0 Zhangfei 0.0

1 Guanyu 1.0

2 a NaN

3 b NaN

4 c NaN

4. right右连接
df3 = pd.merge(df1, df2,how='right') 

def3:

data1 name data2

0.0 Zhangfei 0

1.0 Guanyu 1

NaN A 2

NaN B 3

NaN C 4

5. outer外连接
# 相当与求两个DataFrame的并集
df3 = pd.merge(df1,df2,how = 'outer')

df3:

data1 name data2

0.0 Zhangfei 0.0

1.0 Guanyu 1.0

2.0 a NaN

3.0 b NaN

4.0 c NaN

NaN A 2.0

NaN B 3.0

NaN C 4.0

如何用SQL方式打开Pandas

在python中可以直接使用SQL语句来操作pandas

pandasql:主要函数是sqldf,接收两个参数,一个SQL查询语句,还有一组环境变量,globals()或locals(),这样可以在python中直接使用SQL语句中DataFrame进行操作:

import pandas as pd
from pandas import DataFrame
from pandasql import sqldf , load_meat, load_births
df1 = DataFrame({'name' :  ['Zhangfei' , 'Guanyu' , 'a' , 'b' , 'c'] , ' data1':range(5)})
pysqldf = lambda sql:sqldf(sql , globals())
sql  =  "select * from df1 where name = 'Zhangfei'"
print pysqldf(sql)

lambda用来定义个匿名函数:

lambda arguement_list:experssion

arguement_list是参数列表, experssion是参数的表达式,根据experssion表达式计算结果进行返回

pysqldf = lambda sql:sqldf(sql , globals())

中输入的参数是sql,返回的是sqldf对sql的运行结果,当然sqldf中也输入了globals全局参数,因为在sql中有对全局参数df1的使用

使用DataFrame进行创建并对数据进行清洗,同时新增一列“总和”计算每个人的三科成绩之和

姓名 语文 英语 数学
张飞 66 65
关羽 95 85 98
赵云 95 92 96
黄忠 90 88 77
典韦 80 90 90
典韦 80 90 90
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import pandas as pd

data = {'Chinese': [66, 95, 93, 90, 80, 80], 'English': [65, 85, 92, 88, 90, 90],
        'Math': [None, 98, 96, 77, 90, 90]}
df = pd.DataFrame(data, index=['张飞', '关羽', '赵云', '黄忠', '典韦', '典韦'],
                  columns=['English', 'Math', 'Chinese'])
# 去除重复行
df = df.drop_duplicates()
# 列名重新排序
cols = ['Chinese', 'English', 'Math']
df = df.filter(cols, axis=1)
# 列名改为中文
df.rename(columns={'Chinese': '语文', 'English': '英语',
                   'Math': '数学'}, inplace=True)


def total_score(df):
    df['总分'] = df['语文'] + df['英语'] + df['数学']
    return df


# 求成绩的和,用老师讲的 apply 方法
df = df.apply(total_score, axis=1)
# 或者可以用这个方法求和
# df['总分'] = df['语文'] + df['英语'] + df['数学']
# 按照总分排序,从高到低,此时有缺失值
df.sort_values(['总分'], ascending=[False], inplace=True)
# 打印显示成绩单信息,张飞有空值
print(df.isnull().sum())
print(df.describe())
print(df)

# 使用数学成绩均值填充张飞同学的缺失值
df['数学'].fillna(df['数学'].mean(), inplace=True)
# 再次求成绩的和并打印显示成绩单情况
df = df.apply(total_score, axis=1)
print(df.isnull().sum())
print(df.describe())
print(df)
发布了75 篇原创文章 · 获赞 9 · 访问量 9175

猜你喜欢

转载自blog.csdn.net/ywangjiyl/article/details/104719781