数据蛙数据分析每周作业

第二周:pandas的基础使用和代码

2020-09-10  本文已影响0人  我住永安当

一、Series和DataFrame

1、Series是类似于一维数组的对象,由一组数据(各种numpy的数据类型)以及一组与之相关的标签组成。个人理解,其实就是竖起来的'list'。但是和list不同的是,Series的index是可以在define时就自由设置的。

构建Series的两种写法

```

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

s3 = pd.Series({'a':2,'b':3,'c':4,'d':5})

```

DataFrame(数据框) 是一种二维的数据结构,非常接近于电子表格或者类似 mysql 数据库的形式。它的竖行称之为 columns,横行跟前面的 Series 一样,称之为 index。

二、常见操作

1、Series可以直接转化为数据框:

'''

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

s2=pd.DataFrame(s2)

'''

此时a,b,c,d是作为index出现的

2、索引设置和重命名

如果要把abcd也放入数据框中:需要reset_index()以及rename()

'''

s2=s2.reset_index()

s2

s2=s2.rename(columns={'index':'words',0:'num'})

s2

'''

重命名也可以以直接给columns赋值的方式重命名,但要确保s2为DataFrame:

```

import pandas as pd

s2 = pd.DataFrame(pd.Series([2,3,4,5],index=['a','b','c','d']))

s2=s2.reset_index()

s2.columns=['name','value']

```

3、转置操作

如果需要把数据框进行线代中的‘转置’:(这个步骤没有保存结果到变量s2中)

目前并没有发现实际作用

```

pd.DataFrame(s2).T

```

4、Series

查看数据类型

```

Series名字.dtypes

```

查看所包含元素的个数(index的数量+对应值得数量)
```

Series名字.size

```

索引

```

Series名字.index

```

索引对应的值:返回Series对象中的值部分,ndarray类型

```

Series名字.values

```

查看Series“形状”(也就是行*列)

```

Series名字.shape

```

4行2列

与list类似的是,Series中可以通过索引直接提取对应的值:

```

Series名字['索引值']

```

5、DataFrame

```

DataFrame名字.columns

DataFrame名字.values

DataFrame名字.axes 

```

```
DataFrame名字.index

DataFrame名字.index

```

```

DataFrame名字.shape #查看DataFrame的形状

```

4行2列

6、数据预览

```

df.info() #一般检查下数据是否有缺失值

```

```

df.describe() 

#一般用来查看数值型变量数据的统计学描述:频数count、均值mean、标准差std、最大最小值、上下四分位数(25%、75%)、中位数(50%)

```

···

df.head() 

#查看前X行,默认X=5

df.tail()

#查看末X行,默认X=5

```

···

s2.shape #查看s2的形状

type(s2.shape) #发现数据类型是元祖,所以可以根据索引来选择显示行/列

s2.shape[1] #显示有2列

```

7.读写文件

三篇关于详细参数的解读,部分举例的内容还是对照来看比较好。

pd.read_csv参数详解_orangefly0214的博客-CSDN博客

pd.read_csv() 、to_csv() 之 常用参数 - 喜欢吃面的Hush - 博客园

pandas小记:pandas数据输入输出_皮皮blog-CSDN博客

格式:

储存变量名=pd.read_csv(r'绝对路径')

```

red=pd.read_csv(r'C:\Users\administered\Desktop\\redbookshuju.csv',index_col=0,header=0,skiprows=2)

#index_col 默认值(index_col = None)——重新设置一列成为index值,这一列一般没有意义,无法计入模型进行训练。也可以后面使用drop函数舍弃

#index_col=False——重新设置一列成为index值

#index_col=0——第一列为index值。

#header:指定哪一行作为表头。默认设置为0(即第一行作为表头)。如果文件中没有列名(表头),则默认为0,否则设置为None。如果明确设定header=0 就会用第一行替换掉原来存在列名。

#skiprows=2,表示前面两行[0, 1]都不读入,等价于skiprows=[0, 1]

#个人认为:header、index_col、skiprows应该再head()运行后,依照DataFrame效果再行调整,非必要参数。

```

8、用iloc和loc提取行数据的区别。


Python:loc和iloc的区别_牛仔一灯的博客-CSDN博客

pandas 常用函数_走那条小路-CSDN博客

DataFrame可以用名字['columns名']来进行某一列数据的提取。提取某一行数据需要用这两个函数。

loc——location,i-integer(整数)。因此能够猜到,loc()是根据索引提取值,而iloc是根据行数提取值。

要验证这一点,我们先读取数据:

```

df = pd.read_excel(r'F:\ThunderDownload\new\销售客户信息.xlsx',index_col=0)

#df = pd.read_excel(r'F:\ThunderDownload\new\销售客户信息.xlsx',names=['user_id','login_date',...'])

#可以用names=[]变量加上表头(如果缺少)。

#将第一列用户ID直接作为索引

```

首先取得前六行数据,作为对比

(1)iloc:行数索引

```
df.iloc[4]  #提取第五行

```

```

df[2:4]  #提取第3、4行

```

```
df.iloc[:,:2]  #提取第1、2列

```

(2)loc:index列索引

对应的,loc的索引只需要对应行和列的索引即可,与loc和其他切片方式不同的是,loc无论是以行还是列切片都不遵循左闭右开的规则,即左端点包含右端点不包含的规则。loc切片左右端点均包含:

```

df.loc[10000002:10000004,'会员开通时间':'城市']

#此处原本是想取10000002、10000003两行和会员开通时间、会员类型两列数据。

#但实际运行代码后将10000004行和城市列也取到了。

```

9.columns替换

s2长这摸样

```
s2['name'].replace('a','A',inplace=True)

s2

```

10、数据替换

```

df['性别'].replace('男','Male',inplace=True)

```


11、查看元素的值有哪些

```

DataFrame名字.列名.unique()

DataFrame名字['列名'].unique()

```

12、字段名计数

```

DataFrame名字.列名.value_counts()

DataFrame名字['列名'].value_counts()

```

13、排序

```

DataFrame名字.sort_values('列名',ascending=False)

DataFrame名字['列名'].sort_values(ascending=False)

#默认为升序排列,如果加上ascending=False,降序排列

```

14、聚合函数

```

df.max()

df.min()

df.sum()

#不会单独用,因为在EDA前,数据概览的过程会describe()每个字段的统计学指标。

#一般在创建计算字段时候用。

```

15、删除列/行

```

df=df.drop('列名',axis=1)

df.drop('列名',axis=1,inplace=True)

del df['列名']

 ```

```

df.drop(labels=0,inplace=True)

#labels=行数,此时为第1行

```

16、简单矩阵计算(np.random.random() )

```

df1=pd.DataFrame(np.random.random((5,10)),columns=list('abcdefghij'))

df2=pd.DataFrame(np.random.random((5,10)),columns=list('abcdefghij'))

#生成5行、10列的浮点数,浮点数都是从0-1中随机。

```

简单的矩阵计算满足线代计算法则,对应位置的矩阵数值相加减,或同加同减一个数

```

df1+df2

df1-10

```

17、取得列极值数据所映射的索引值( idxmax()/idxmin() )

```pandas数组获取最大值索引的方法-argmax和idxmax - 诗&远方 - 博客园

countries = [

    'Afghanistan', 'Albania', 'Algeria', 'Angola',

    'Argentina', 'Armenia', 'Australia', 'Austria',

    'Azerbaijan', 'Bahamas', 'Bahrain', 'Bangladesh',

    'Barbados', 'Belarus', 'Belgium', 'Belize',

    'Benin', 'Bhutan', 'Bolivia', 'Bosnia and Herzegovina',

]

employment_values = [

    55.70000076,  51.40000153,  50.5      ,  75.69999695,

    58.40000153,  40.09999847,  61.5      ,  57.09999847,

    60.90000153,  66.59999847,  60.40000153,  68.09999847,

    66.90000153,  53.40000153,  48.59999847,  56.79999924,

    71.59999847,  58.40000153,  70.40000153,  41.20000076,

]

#创建数据

```

这两个函数同样适用于DataFrame、Series、没有设置索引的Series

```

df.字段名.idxmax()

df.字段名.idxmin()

```


可以看到,如果创建的是DataFrame返回值是对应的索引名 可以看到,如果创建的是有索引的Series返回值是对应的索引名    可以看到,如果创建的是没有索引的Series返回值是对应的行数     

18、拼接

(1)硬拼,数据不改变:pandas下面的concat函数

首先构造一个列明相同的列表组合:

```

left = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],

                      'A': ['A0', 'A1', 'A2', 'A3'],

                      'B': ['B0', 'B1', 'B2', 'B3']})

right = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],

                      'A': ['C0', 'C1', 'C2', 'C3'],

                      'B': ['D0', 'D1', 'D2', 'D3']})

```

纵向拼接

```

pd.concat([left,right])

如果要忽略两列的索引,可以键入参数 ignore_index=True

```

横向拼接

```

pd.concat([left,right],axis=1)

```

(2)软拼,需要关联数据:merge()函数

pd.merge操作的on参数解释 - 月下林白 - 博客园

pd.merge(数据组1,数据组2,how=inner,on=[],left_on=[],right_on=[],left_index=,right_index=)

# 通过指定 how 来确定关联方式

#左连接

result = pd.merge(left, right, how='left', on=['key1', 'key2'])

#右连接

result = pd.merge(left, right, how='right', on=['key1', 'key2'])

#外连接

result = pd.merge(left, right, how='outer', on=['key1', 'key2'])

result

一个关键字进行关联:

left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],

                      'key2': ['K0', 'K1', 'K0', 'K1'],

                      'A': ['A0', 'A1', 'A2', 'A3'],

                      'B': ['B0', 'B1', 'B2', 'B3']})

right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],

                      'key2': ['K0', 'K0', 'K0', 'K0'],

                      'C': ['C0', 'C1', 'C2', 'C3'],

                      'D': ['D0', 'D1', 'D2', 'D3']})

```

result = pd.merge(left,right,on='key')

result

```

多个关键字进行关联:

left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],

                      'key2': ['K0', 'K1', 'K0', 'K1'],

                      'A': ['A0', 'A1', 'A2', 'A3'],

                      'B': ['B0', 'B1', 'B2', 'B3']})

right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],

                      'key2': ['K0', 'K0', 'K0', 'K0'],

                      'C': ['C0', 'C1', 'C2', 'C3'],

                      'D': ['D0', 'D1', 'D2', 'D3']})

result = pd.merge(left, right, on=['key1', 'key2'])

result

列名不一样怎么关联:

left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],

                      'key2': ['K0', 'K1', 'K0', 'K1'],

                      'A': ['A0', 'A1', 'A2', 'A3'],

                      'B': ['B0', 'B1', 'B2', 'B3']})

right = pd.DataFrame({'key3': ['K0', 'K1', 'K1', 'K2'],

                      'key4': ['K0', 'K0', 'K0', 'K0'],

                      'C': ['C0', 'C1', 'C2', 'C3'],

                      'D': ['D0', 'D1', 'D2', 'D3']})

pd.merge(left,right,left_on = ['key1','key2'],right_on = ['key3','key4'])

通过索引进行关联:

left.set_index('key1',inplace=True)

right.set_index('key3',inplace=True)

#此时key2、key4作为列名出现在DataFrame中了

pd.merge(left,right,left_index=True,right_index=True)

19、transform/apply/agg函数的联系与区别:计算

pandas:apply和transform方法的性能比较 - Bo_hemian - 博客园

pandas中 transform 函数和 apply 函数的区别_mike_jun的博客-CSDN博客

其中,agg()+python内置方法是运行速度最快的。

(1)transform函数的用法

与其他三者最为不同的是,apply和agg的长度和groupby之前的数据长度是不同的,因此创建新的计算变量时,transform函数可以直接引入,而apply和agg则会出现Nan。也就是说,transform返回与数据同样长度的行,而apply和agg则进行了聚合。

同时,trasform只能对单列Series进行处理


transform返回与groupby()前相同长度的数据,apply返回和groupby()相同长度的数据。transform得到的Series的索引总是数字,而并不是groupby的变量。 agg返回和groupby()相同长度的数据

s_score = lambda s : (s-s.mean())/s.std()

#此处相当于一个数据标准化的处理

groups = df.groupby("district")

groups[['age','novip_buy_times','novip_buy_moneys']].transform(s_score)

```

(2)apply函数的用法

apply()里面可以跟自定义的函数,包括简单的求和函数以及复杂的特征间的差值函数等(注:apply不能直接使用agg()方法 / transform()中的python内置函数,例如sum、max、min、’count‘等方法

结合匿名函数定义各种运算,应该是这几个函数中应用最宽泛的一个。

apply不能直接引用python内置函数,必须结合lambda定义映射规则 与agg函数不同的是,apply不可以返回列表的值


(3)agg函数的用法

python中的agg函数通常用于调用groupby()函数之后,对数据做一些聚合操作,包括sum,min,max以及其他一些聚合函数

以此数据为例:

data = {'性别':['男','女','女','男','男'],

        '姓名':['小明','小红','小芳','大黑','张三'],

        '身高':[178,173,165,188,156],

        '年龄':[20,20,25,24,29]}

df = pd.DataFrame(data)

单字段与单列Python内置函数连用

```

df.groupby('性别').agg({'身高':min})

df.groupby('性别')['身高'].agg([min])

df.groupby('性别')['身高'].agg(min)  #返回的是一个Series

```

单字段与多列Python内置函数连用

```

df.groupby('性别').agg({'身高':[max,min]})

df.groupby('性别')['身高'].agg([max,min])

```

多字段与多列Python内置函数连用

```

df.groupby('性别').agg({'身高':[max,min],'年龄':min})

```

如图,性别作为index传导到结果中了

单/多字段与匿名函数连用

```

df.groupby('性别')['身高'].agg(lambda x:x.min())

df.groupby('性别')['身高','年龄'].agg(lambda x:x.min())

```

此处关于内置函数与匿名函数区别的理解:

agg函数如果不嵌套匿名函数,在确定传导变量和函数时,是有返回值的。所以agg(apply,transform应该也是同理)(min())反而是错的

lambda本身只是一个映射规则,没有返回值。如果没有(),相当于只调用了函数,返回的是这个函数。

```

df.groupby('性别')['身高'].agg([lambda x:x.max(),lambda x:x.min()])

df.groupby('性别')['身高'].agg([lambda x:x.max,lambda x:x.min])

```

通常在调用完agg函数后需要reset_index,因为pandas会默认将groupby()的列也做为index传到结果中

20、apply()和filter():筛选

(1)filter函数的用法

Pandas:细说groupby和aggregate、transform、apply以及filter_小龙虾-CSDN博客

主要用于groupby后的筛选,功能性上类似于MySql中的wherewhere语句。

DataFrame.filter(self,items=None,like=None,regex=None,axis=None)

目前的水平暂时用不到正则表达式,axis一般不需要自定义,列名筛选用filter函数太过多余。因此此处只讨论filter与匿名函数的联用。

先看一下数据帧的head()

district代表地区的变量

```
group_new=df.groupby('district')

a=group_new.filter(lambda x:np.max(x['vip_buy_moneys'])>=5000)

```

此处需注意:

"filter返回的是布尔运算的结果,即True或者False"——因此需要用list提取你想要看到的字段的列表。

"整个filter返回的结果,是那些满足条件的子数据帧,这些子数据帧要么全返回,要么一个都不返回,所以,groupby后面用filter,是挑选“我想要的那些子数据帧”,最小单位为子数据帧,而不是子数据帧里面的某些行,这点要尤其注意!"——因此在groupby筛选后得到的实际是一个数据帧(DataFrame),需要看什么字段可以直接指定列名。

"filter是唯一一个不能用df.group('XXX')['列名'].filter来指定列的函数,因为filter挑选出来的是子数据帧,跟列无关。"——写法上要注意,groupby()后不可以指定列

(2)apply做筛选

group_new_1=df.groupby('district')

a=group_new_1.apply(lambda x:np.max(x['vip_buy_moneys'])>=5000)

type(a)

sum(a)

21、分组操作(聚合)

a=数据组名字.groupby('字段名')

后接.size() 查看包含数据量 

len(a)查看分组数

分组后每组计数:a.value_counts()

分组过滤

此处涉及到一个filter函数的用法:Python3 filter() 函数 | 菜鸟教程

df2 = groups.filter(lambda g : g['vip_buy_moneys'].mean() >= 2000)

#filter中包含了一个匿名函数,规则是vip_buy_moneys的平均值不小于2000

三、pandas连接SQL

当能用workbench等图形化操作界面登录MySQL却忘记root密码时如何查看密码。_qq_44962541的博客-CSDN博客

1、导入模块

import pandas as pd

import sqlalchemy

2、创建sql语句和engine

sql='select * from temp'

engine = sqlalchemy.create_engine('mysql+pymysql://root:root@localhost:3306/new_homework')

#固定写法端口(不变)  engine = sqlalchemy.create_engine('mysql+pymysql://

#账号 root

#密码 root

#本地的Mysql端口(不变)  @localhost:3306

#数据库 data

3、读取数据

df=pd.read_sql(sql,engine)

4、写入数据

df1 = pd.DataFrame(columns={'DATE':['2019-2-10'],'value':[12]},index=['7'])  #写入一行数据

#此处如果不规定index,则默认从0开始,代码运行虽然成功,但实际数据并没有写入到数据库中。

df1.to_sql('temp',engine,index=False,if_exists='append')

df

上一篇下一篇

猜你喜欢

热点阅读