一、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)
'''

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
```

与list类似的是,Series中可以通过索引直接提取对应的值:
```
Series名字['索引值']
```

5、DataFrame
```
DataFrame名字.columns
DataFrame名字.values
DataFrame名字.axes
```


```
DataFrame名字.index
DataFrame名字.index
```


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

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博客
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['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()
```






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进行处理。


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‘等方法)
结合匿名函数定义各种运算,应该是这几个函数中应用最宽泛的一个。




(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})
```

单/多字段与匿名函数连用
```
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()

```
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

网友评论