本内容来自《跟着迪哥学Python数据分析与机器学习实战》,该篇博客将其内容进行了整理,加上了自己的理解,所做小笔记。若有侵权,联系立删。
迪哥说以下的许多函数方法都不用死记硬背,多查API多看文档,确实,跟着迪哥混就完事了~~~
Pandas官网API

以下代码段均在Jupyter Notebook下进行运行操作
每天过一遍,腾讯阿里明天见~

Pandas工具包是专门用作数据处理和分析的,其底层的计算其实都是由Numpy来完成。

一、数据预处理

titanic.csv

Ⅰ,数据读取

将下载好的泰坦尼克号成员名单数据集放到Jupyter Notebook同级目录下
需要指定好数据的路径,至于read_csv()函数,默认读取的数据格式是.csv,也就是以逗号为分隔符的数据集
df.head(10)表示展示其中前10条数据
df.tail(10)表示展示其中后10条数据

import pandas as pd
import numpy as np
df = pd.read_csv('titanic.csv')#指定数据集路径
df.head(10)#不填参数默认展示前5条

df.tail(10)#不填参数默认展示后5条

Ⅱ,DataFrame结构

df是Pandas工具包中最常见的基础结构
pandas.core.frame.DataFrame可以把它当作是一个二维矩阵结构
基本上读取数据返回的都是DataFrame结构
df.info()函数用于打印当前读取数据的部分信息,包括数据样本规模、每列特征类型与个数、整体的内存占用等

df.info()
"""
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):#   Column       Non-Null Count  Dtype
---  ------       --------------  -----  0   PassengerId  891 non-null    int64  1   Survived     891 non-null    int64  2   Pclass       891 non-null    int64  3   Name         891 non-null    object 4   Sex          891 non-null    object 5   Age          714 non-null    float646   SibSp        891 non-null    int64  7   Parch        891 non-null    int64  8   Ticket       891 non-null    object 9   Fare         891 non-null    float6410  Cabin        204 non-null    object 11  Embarked     889 non-null    object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.7+ KB
"""

返回索引

df.index
"""
RangeIndex(start=0, stop=891, step=1)
"""

拿到每一列特征的信息

df.columns
"""
Index(['PassengerId', 'Survived', 'Pclass', 'Name', 'Sex', 'Age', 'SibSp','Parch', 'Ticket', 'Fare', 'Cabin', 'Embarked'],dtype='object')
"""

返回每一列特征的类型,其中object为python中的字符串类型

df.dtypes
"""
PassengerId      int64
Survived         int64
Pclass           int64
Name            object
Sex             object
Age            float64
SibSp            int64
Parch            int64
Ticket          object
Fare           float64
Cabin           object
Embarked        object
dtype: object
"""

返回数据矩阵

df.values
"""
array([[1, 0, 3, ..., 7.25, nan, 'S'],[2, 1, 1, ..., 71.2833, 'C85', 'C'],[3, 1, 3, ..., 7.925, nan, 'S'],...,[889, 0, 3, ..., 23.45, nan, 'S'],[890, 1, 1, ..., 30.0, 'C148', 'C'],[891, 0, 3, ..., 7.75, nan, 'Q']], dtype=object)
"""

Ⅲ,数据索引

通过指定名字来取其中某一列指标

age = df['Age']
age[0:5]
"""
0    22.0
1    38.0
2    26.0
3    35.0
4    35.0
Name: Age, dtype: float64
"""

在读取数据时,read_csv()函数会默认把读取数据中的第一行当作列名
对其中的数值进行操作

age.values[0:5]
"""
array([22., 38., 26., 35., 35.])
"""

可以将姓名设置为索引,也可以自己设置其他索引。

df = df.set_index('Name')
df.head(6)


如果想得到某个乘客的特征信息,可以直接通过姓名来查找

age = df['Age']
age['Allen, Mr. William Henry']
"""
35.0
"""

要通过索引来取某一部分具体数据,指定具体的几列

df[['Age','Fare']][0:5]


.iloc():用位置找数据
第一列是用户的信息特征,第二列是信息所对应的数据

df.iloc[0]
"""
PassengerId            1
Survived               0
Pclass                 3
Sex                 male
Age                   22
SibSp                  1
Parch                  0
Ticket         A/5 21171
Fare                7.25
Cabin                NaN
Embarked               S
Name: Braund, Mr. Owen Harris, dtype: object
"""

使用切片获取一部分数据

df.iloc[0:5]


也可以指定特征

df.iloc[0:5,1:3]


.loc():用标签找数据
以名字为索引,指定名字来获取该人的数据信息

df = df.set_index('Name')
df.loc['Heikkinen, Miss. Laina']
"""
PassengerId                   3
Survived                      1
Pclass                        3
Sex                      female
Age                          26
SibSp                         0
Parch                         0
Ticket         STON/O2. 3101282
Fare                      7.925
Cabin                       NaN
Embarked                      S
Name: Heikkinen, Miss. Laina, dtype: object
"""

取当前数据的某一列信息

df.loc['Heikkinen, Miss. Laina','Fare']
"""
7.925
"""

选择多个样本,例如从狗蛋儿到王二麻子之间的所有人信息

df.loc['Heikkinen, Miss. Laina':'Allen, Mr. William Henry',:]


可以对数据进行赋值

df.loc['Heikkinen, Miss. Laina','Fare'] = 1000
df.iloc[0:5]


bool类型同样可以当作索引
筛选Fare大于40的旅客信息,因为前面以及将姓名作为索引了,故这里只展示姓名信息

df['Fare'] > 40
"""
Name
Braund, Mr. Owen Harris                                False
Cumings, Mrs. John Bradley (Florence Briggs Thayer)     True
Heikkinen, Miss. Laina                                  True
Futrelle, Mrs. Jacques Heath (Lily May Peel)            True
Allen, Mr. William Henry                               False...
Montvila, Rev. Juozas                                  False
Graham, Miss. Margaret Edith                           False
Johnston, Miss. Catherine Helen "Carrie"               False
Behr, Mr. Karl Howell                                  False
Dooley, Mr. Patrick                                    False
Name: Fare, Length: 891, dtype: bool
"""

展示Fare大于40的前五个旅客所有信息

df[df['Fare'] > 40] [0:5]


筛选前五个性别是男的旅客全部信息

df[df['Sex'] == 'male'] [0:5]


计算所有男性旅客的平均年龄

df.loc[df['Sex'] == 'male','Age'].mean()
"""
30.72664459161148
"""

统计年龄超过70岁的旅客有几个

(df['Age']>70).sum()
"""
5
"""

Ⅳ,创建DataFrame

DataFrame是通过读取数据得到的
想展示某些信息,也可以自己创建
最简单的方法就是创建一个字典结构,其中key表示特征名字,value表示各个样本的实际值,然后通过pd.DataFrame()函数来创建

data = {'country':['China','America','India'],'population':[14,3,12]}
df_data = pd.DataFrame(data)
df_data


如果数据量过多,读取的数据不会全部显示,而是会隐藏部分数据,这时可以通过设置参数来控制显示结果
get_option可以查看默认显示的最大行数

pd.get_option('display.max_rows')
"""
60
"""

get_option可以查看默认最大显示的列数

pd.get_option('display.max_columns')
"""
20
"""

由于设置了display.max_rows=6,因此只显示其中6条数据,其余省略了

pd.set_option('display.max_rows',6)
pd.Series(index=range(0,100))
"""
0    NaN
1    NaN
2    NaN..
97   NaN
98   NaN
99   NaN
Length: 100, dtype: float64
"""

如果数据特征稍微有点多,可以设置得更大一些

pd.set_option('display.max_columns',30)
pd.DataFrame(columns = range(0,30))

Ⅴ,Series操作

前面提到的操作对象都是DataFrame
Series简单来说,读取的数据都是二维的,也就是DataFrame
如果在数据中单独取某列数据,那就是Series格式了,相当于DataFrame是由Series组合起来得到的

创建Series

data = [5,22,10,14,12,6]
index = ['b','e','y','o','n','d']
s = pd.Series(data=data,index=index)
s
"""
b     5
e    22
y    10
o    14
n    12
d     6
dtype: int64
"""

通过索引查询操作与DataFrame是一样的
查看key为’b’所对应的数据的值

s.loc['b']
"""
5
"""

查看下标为1的数据的值

s.iloc[1]
"""
22
"""

改值操作

s1 = s.copy()
s1['o'] = 100
s1
"""
b      5
e     22
y     10
o    100
n     12
d      6
dtype: int64
"""

也可以使用replace()函数
replace()函数的参数中多了一项inplace
如果设置inplace=False,就是不将结果赋值给变量,只相当于打印操作
如果设置inplace=True,就是直接在数据中执行实际变换,而不仅是打印操作

s1.replace(to_replace=100,value=101,inplace=True)
s1
"""
b      5
e     22
y     10
o    101
n     12
d      6
dtype: int64
"""

以改索引操作

s1.index
"""
Index(['b', 'e', 'y', 'o', 'n', 'd'], dtype='object')
"""

方法一

s1.index = ['b', 'e', 'Y', 'o', 'n', 'd']
s1
"""
b      5
e     22
Y     10
o    101
n     12
d      6
dtype: int64
"""

方法二

s1.rename(index = {'b':'B'},inplace=True)
s1
"""
B      5
e     22
Y     10
o    101
n     12
d      6
dtype: int64
"""

增操作

data = [55,99]
index = ['y','q']
s2 = pd.Series(data=data,index=index)
s2
"""
y    55
q    99
dtype: int64
"""
s3 = s1.append(s2)
s3
"""
B      5
e     22
Y     10
o    101
n     12
d      6
y     55
q     99
dtype: int64
"""
s3['y'] = 500
s3
"""
B      5
e     22
Y     10
o    101
n     12
d      6
y    500
q     99
dtype: int64
"""

删操作

s1
"""
B      5
e     22
Y     10
o    101
n     12
d      6
dtype: int64
"""
del s1['e']
s1
"""
B      5
Y     10
o    101
n     12
d      6
dtype: int64
"""

也可以直接del选中数据的索引进行删除

s1.drop(['n','d'],inplace=True)
s1
"""
B      5
Y     10
o    101
dtype: int64
"""

二、数据分析

Ⅰ,统计分析

在DataFrame中对数据进行计算跟Numpy差不多,默认都是对整体进行操作

df = pd.DataFrame([[1,2,3],[7,4,1]],index=['a','b'],columns=['A','B','C'])
df


对数据求和

df.sum()#默认按列求和,即axis=0
"""
A    8
B    6
C    4
dtype: int64
"""
df.sum(axis=1)
"""
a     6
b    12
dtype: int64
"""

对数据求均值

df.mean()
"""
A    4.0
B    3.0
C    2.0
dtype: float64
"""
df.mean(axis=1)
"""
a    2.0
b    4.0
dtype: float64
"""

求数据的中位数

df.median()
"""
A    4.0
B    3.0
C    2.0
dtype: float64
"""
df.median(axis=1)
"""
a    2.0
b    4.0
dtype: float64
"""

求数据的最大值

df.max()
"""
A    7
B    4
C    3
dtype: int64
"""
df.max(axis=1)
"""
a    3
b    7
dtype: int64
"""

求数据的最小值

df.min()
"""
A    1
B    2
C    1
dtype: int64
"""
df.min(axis=1)
"""
a    1
b    1
dtype: int64
"""

使用describe()函数,既可以得到各项统计指标,也可以观察数据是否存在

df.describe()


下面开始对泰坦尼克号旅客信息进行操作

df = pd.read_csv('titanic.csv')
df.describe()


协方差矩阵

df.cov()


相关系数

df.corr()


统计某一列各个属性的比例情况,需要使用value_counts()函数

统计性别这一列中所有属性的个数

df['Sex'].value_counts()
"""
male      577
female    314
Name: Sex, dtype: int64
"""

指定顺序,个数少的排在前面,即从小到大排序

df['Sex'].value_counts(ascending=True)
"""
female    314
male      577
Name: Sex, dtype: int64
"""

像年龄这种离散型指标就显得不太好处理

df['Age'].value_counts(ascending=True)
"""
0.42      1
23.50     1
66.00     1
70.50     1
55.50     1..
30.00    25
19.00    25
18.00    26
22.00    27
24.00    30
Name: Age, Length: 88, dtype: int64
"""

把所有年龄这一列中的所有数据平均分为为5组,因为ascending=True故从小到大排序

df['Age'].value_counts(ascending=True,bins=5)
"""
(64.084, 80.0]       11
(48.168, 64.084]     69
(0.339, 16.336]     100
(32.252, 48.168]    188
(16.336, 32.252]    346
Name: Age, dtype: int64
"""

创建一个年龄数组ages,然后指定4个判断值,接下来就用这4个值把数据分成(0,10],(10,15],(15,30]这三组,返回的结果分别表示当前年龄属于哪组。

ages = [15,18,2,4,22,13,10,26,29]
bins = [0,10,15,30]
bins_res = pd.cut(ages,bins)
bins_res
"""
[(10, 15], (15, 30], (0, 10], (0, 10], (15, 30], (10, 15], (0, 10], (15, 30], (15, 30]]
Categories (3, interval[int64]): [(0, 10] < (10, 15] < (15, 30]]
"""

可以打印其默认标签值,当前分组结果

bins_res.codes
"""
array([1, 2, 0, 0, 2, 1, 0, 2, 2], dtype=int8)
"""

各组总人数

pd.value_counts(bins_res)
"""
(15, 30]    4
(0, 10]     3
(10, 15]    2
dtype: int64
"""

分为四组

pd.cut(ages,[0,10,30,50,80])
"""
[(10, 30], (10, 30], (0, 10], (0, 10], (10, 30], (10, 30], (0, 10], (10, 30], (10, 30]]
Categories (4, interval[int64]): [(0, 10] < (10, 30] < (30, 50] < (50, 80]]
"""

自己给这四组进行定义标签

group_names = ['baby','teenage','adult','older']
pd.value_counts(pd.cut(ages,[0,10,30,50,80],labels=group_names))
"""
teenage    6
baby       3
older      0
adult      0
dtype: int64
"""

Ⅱ,pivot数据透视表

随便创建点数据,其中Category表示把钱花在什么用途上(如交通运输、家庭、娱乐等费用),Month表示统计月份,Amount表示实际的花费。

example = pd.DataFrame({'Month':["January","January","January","January","February","February","February","February","March","March","March","March"],'Category':["Transportation","Grocery","Household","Entertainment","Transportation","Grocery","Household","Entertainment","Transportation","Grocery","Household","Entertainment"],'Amount':[74.,235.,175.,100.,115.,240.,225.,125.,90.,26.,200.,120.]})
example


统计的每个月花费在各项用途上的金额分别是多少

example_pivot = example.pivot(index='Category',columns="Month",values="Amount")
example_pivot


这几个月中每项花费的总额

example_pivot.sum(axis=1)
"""
Category
Entertainment     345.0
Grocery           501.0
Household         600.0
Transportation    279.0
dtype: float64
"""

每个月所有花费的总额

example_pivot.sum(axis=0)
"""
Month
February    705.0
January     584.0
March       436.0
dtype: float64
"""

使用泰坦尼克号旅客信息来进行实操
Pclass表示船舱等级,Fare表示船票的价格
按乘客的性别分别统计各个舱位购票的平均价格
index指定了按照什么属性来统计,columns指定了统计哪个指标,values指定了统计的实际指标值是什么

df = pd.read_csv('titanic.csv')
df.pivot_table(index='Sex',columns='Pclass',values='Fare')


平均值相当于是默认值,如果想指定最大值或者最小值,还需要额外指定aggfunc来明确结果的含义

df.pivot_table(index='Sex',columns='Pclass',values='Fare',aggfunc='max')


统计各个船舱等级的人数

df.pivot_table(index='Sex',columns='Pclass',values='Fare',aggfunc='count')


首先按照年龄将乘客分成两组:成年人和未成年人。再对这两组旅客分别统计不同性别的人的平均获救可能性

df['Underaged'] = df['Age'] <= 18
df.pivot_table(index='Underaged',columns='Sex',values='Survived',aggfunc='mean'

Ⅲ,groupby操作

df = pd.DataFrame({'key':['A','B','C','A','B','C','A','B','C'],'data':[0,5,10,5,10,15,10,15,20]})
df


统计各个key中对应的data数值总和,一般方法

for key in['A','B','C']:print(key,df[df['key'] == key].sum())
"""
A key     AAA
data     15
dtype: object
B key     BBB
data     30
dtype: object
C key     CCC
data     45
dtype: object
"""

统计各个key中对应的data数值总和,groupby

df.groupby('key').sum()


统计各个key中对应的data均值,groupby

df.groupby('key').aggregate(np.mean)


使用泰坦尼克号旅客数据集,按照不同性别统计其年龄的平均值

df = pd.read_csv('titanic.csv')
df.groupby('Sex')['Age'].mean()
"""
Sex
female    27.915709
male      30.726645
Name: Age, dtype: float64
"""

groupby()函数中还有很多参数可以设置

df = pd.DataFrame({'A':['foo','bar','foo','bar','foo','bar','foo','foo'],'B':['one','one','two','three','two','two','one','three'],'C':np.random.randn(8),'D':np.random.randn(8)})
df


观察groupby某一列(A列)后结果的数量

grouped = df.groupby('A')
grouped.count()


观察groupby某一列(A、B列)后结果的数量

grouped = df.groupby(['A','B'])
grouped.count()


求和

grouped = df.groupby(['A','B'])
grouped.aggregate(np.sum)


加入索引,按照传入参数的顺序来指定

grouped = df.groupby(['A','B'],as_index=False)
grouped.aggregate(np.sum)


使用describe()方法来展示前5条统计信息

grouped.describe().head()


可以自己设置需要的统计指标

grouped = df.groupby('A')
grouped['C'].agg([np.sum,np.mean,np.std])

在groupby操作中还可以指定操作的索引(也就是level)

arrays = [['bar','bar','baz','baz','foo','foo','qux','qux'],['one','two','one','two','one','two','one','two']]
index = pd.MultiIndex.from_arrays(arrays,names=['first','second'])
index
"""
MultiIndex([('bar', 'one'),('bar', 'two'),('baz', 'one'),('baz', 'two'),('foo', 'one'),('foo', 'two'),('qux', 'one'),('qux', 'two')],names=['first', 'second'])
"""

光有索引还不够,还需要具体数值

s = pd.Series(np.random.randn(8),index=index)
s
"""
first  second
bar    one       0.334041two      -0.370639
baz    one       0.932589two      -1.047145
foo    one      -1.004788two      -0.197581
qux    one      -1.114047two       1.019581
dtype: float64
"""

通过level参数可以指定以哪项为索引进行计算
当level为0时,设置名为first的索引
当level为1时,设置名为second的索引

grouped = s.groupby(level=0)
grouped.sum()
"""
first
bar   -0.036598
baz   -0.114556
foo   -1.202369
qux   -0.094466
dtype: float64
"""
grouped = s.groupby(level=1)
grouped.sum()
"""
second
one   -0.852205
two   -0.595784
dtype: float64
"""

如果觉得指定一个数值不够直观,也可以直接用具体名字,结果相同

grouped = s.groupby(level='first')
grouped.sum()
"""
first
bar   -0.036598
baz   -0.114556
foo   -1.202369
qux   -0.094466
dtype: float64
"""

三、常用函数操作

Ⅰ,Merge操作

先创建两个DataFrame,key值相同

left = pd.DataFrame({'key':['K0','K1','K2','K3'],'A':['A0','A1','A2','A3'],'B':['B0','B1','B2','B3']})
left

right = pd.DataFrame({'key':['K0','K1','K2','K3'],'C':['C0','C1','C2','C3'],'D':['D0','D1','D2','D3']})
right


按照key列把两份数据整合在一起,这里的key值是一样的

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


再创建两个DataFrame,key1列和key2列的前3行都相同,但是第4行的值不同

left = pd.DataFrame({'key1':['K0','K1','K2','K3'],'key2':['K0','K1','K2','K3'],'A':['A0','A1','A2','A3'],'B':['B0','B1','B2','B3']})
left

right = pd.DataFrame({'key1':['K0','K1','K2','K3'],'key2':['K0','K1','K2','K4'],'C':['C0','C1','C2','C3'],'D':['D0','D1','D2','D3']})
right


前3行相同的都组合在一起了,但是第4行却被直接抛弃了

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


额外设置一个how参数,将抛弃的第4行给显示

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


还可以加入详细的组合说明,指定indicator参数为True即可

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


单独设置只考虑左边数据或者只考虑右边数据

res = pd.merge(left,right,how='left')
res

res = pd.merge(left,right,how='right')
res

Ⅱ,排序操作

创建一个DataFrame

data = pd.DataFrame({'group':['a','a','a','b','b','b','c','c','c'],'data':[0,5,22,10,14,99,98,19,7]})
data


可以指定升序或者降序,并且还可以指定按照多个指标排序
首先对group列按照降序进行排列,在此基础上保持data列是升序排列,其中by参数用于设置要排序的列,ascending参数用于设置升降序

data.sort_values(by=['group','data'],ascending=[False,True],inplace=True)
data

Ⅲ,缺失值处理

创建一组数据用乘法来创建一组有重复部分的数据

data = pd.DataFrame({'k1':['one']*3 + ['two']*4,'k2':[3,2,1,5,5,10,14]})
data


使用drop_duplicates()函数去掉多余的数据

data.drop_duplicates()


只考虑某一列的重复情况,其他全部舍弃

data.drop_duplicates(subset='k1')


直接指定新的列名或者使用assign()函数要往数据中添加新的列

df = pd.DataFrame({'data1':np.random.randn(5),'data2':np.random.randn(5)})
df1 = df.assign(ration=df['data1']/df['data2'])
df1


数据处理过程中经常会遇到缺失值,Pandas中一般用NaN来表示(Not a Number)

df = pd.DataFrame([range(3),[0,np.nan,0],[0,0,np.nan],range(3)])
df


通过isnull()函数判断所有缺失情况

df.isnull()


输出某列是否存在缺失值,其中.any()函数相当于只要有一个缺失值就意味着存在缺失情况

df.isnull().any()
"""
0    False
1     True
2     True
dtype: bool
"""

可以自己指定检查的维度

df.isnull().any(axis=1)
"""
0    False
1     True
2     True
3    False
dtype: bool
"""

缺失值填充,fillna()函数可以对缺失值进行填充,这里只选择一个数值,实际中更常使用的是均值、中位数,具体情况具体分析

df.fillna(5)

Ⅳ,apply自定义函数

首先定义一个映射函数

data = pd.DataFrame({'food':['A1','A2','B1','B2','B3','C1','C2'],'data':[1,4,7,8,5,2,3]})
data


apply()函数使用,需要先写好要执行操作的函数,接下来直接调用即可,相当于对数据中所有样本都执行这样的操作

def food_map(series):if series['food'] == 'A1':return 'A'elif series['food'] == 'A2':return 'A'elif series['food'] == 'B1':return 'B'elif series['food'] == 'B2':return 'B'elif series['food'] == 'B3':return 'B'elif series['food'] == 'C1':return 'C'elif series['food'] == 'C2':return 'C'data['food_map'] = data.apply(food_map,axis='columns')
data


使用泰坦尼克号旅客信息运用apply()函数
统计每列的缺失值个数,写好自定义函数之后依旧调用apply()函数,这样每列特征的缺失值个数就统计出来了

titanic = pd.read_csv('titanic.csv')
def nan_count(columns):columns_null = pd.isnull(columns)null = columns[columns_null]return len(null)columns_null_count = titanic.apply(nan_count)
columns_null_count
"""
PassengerId      0
Survived         0
Pclass           0
Name             0
Sex              0
Age            177
SibSp            0
Parch            0
Ticket           0
Fare             0
Cabin          687
Embarked         2
dtype: int64
"""

统计一下每一位乘客是否是成年人

def is_minor(row):if row['Age'] < 18:return Trueelse:return False
minors = titanic.apply(is_minor,axis=1)
minors
"""
0      False
1      False
2      False
3      False
4      False...
886    False
887    False
888    False
889    False
890    False
Length: 891, dtype: bool
"""

Ⅴ,时间操作

创建一个时间戳

ts = pd.Timestamp('2022-5-3')
ts
"""
Timestamp('2022-05-03 00:00:00')
"""
ts.month
"""
5
"""
ts.day
"""
3
"""
ts + pd.Timedelta('7 days')
"""
Timestamp('2022-05-10 00:00:00')
"""
s = pd.Series(['2022-5-3 21:40:10','2022-5-4 10:14:05','2022-5-5 05:22:06'])
s
"""
0    2022-5-3 21:40:10
1    2022-5-4 10:14:05
2    2022-5-5 05:22:06
dtype: object
"""
ts = pd.to_datetime(s)
ts
"""
0   2022-05-03 21:40:10
1   2022-05-04 10:14:05
2   2022-05-05 05:22:06
dtype: datetime64[ns]
"""
ts.dt.hour
"""
0    21
1    10
2     5
dtype: int64
"""
ts.dt.weekday
"""
0    1
1    2
2    3
dtype: int64
"""

知道数据的采集时间,并且每条数据都是固定时间间隔保存

pd.Series(pd.date_range(start='2022-5-3',periods=14,freq='12H'))
"""
0    2022-05-03 00:00:00
1    2022-05-03 12:00:00
2    2022-05-04 00:00:00
3    2022-05-04 12:00:00
4    2022-05-05 00:00:00
5    2022-05-05 12:00:00
6    2022-05-06 00:00:00
7    2022-05-06 12:00:00
8    2022-05-07 00:00:00
9    2022-05-07 12:00:00
10   2022-05-08 00:00:00
11   2022-05-08 12:00:00
12   2022-05-09 00:00:00
13   2022-05-09 12:00:00
dtype: datetime64[ns]
"""

以时间特征为索引,可以将parse_dates参数设置为True
flowdata数据集

data = pd.read_csv('flowdata.csv',index_col=0,parse_dates=True)
data


有了索引后,就可以用它来取数据

data[pd.Timestamp('2012-01-01 09:00'):pd.Timestamp('2012-01-01 19:00')]


取2013年的数据
也用data[‘2012-01’:‘2012-03’]指定具体月份,或者更细致一些,在小时上继续进行判断
例如:data[(data.index.hour>8)&(data.index.hour<12)]

data['2013']


resample重采样
原始数据中每天都有好几条数据,统计每天的平均指标

data.resample('D').mean().head()


按3天为一个周期进行统计

data.resample('3D').mean().head()


按月进行统计

data.resample('M').mean().head()

Ⅵ,绘图操作

%matplotlib inline#在Jupyter Notebook中使用绘图操作需要先执行此命令
df = pd.DataFrame(np.random.randn(10,4).cumsum(0),index=np.arange(0,100,10),columns=['A','B','C','D'])
df.plot()
"""
<AxesSubplot:>
"""


同时展示两个图表,用到子图

import matplotlib.pyplot as plt
fig,axes = plt.subplots(2,1)#指定子图为2行1列
data = pd.Series(np.random.rand(16),index=list('abcdefghijklmnop'))
data.plot(ax=axes[0],kind='bar')#axes[0]为第一个子图
data.plot(ax=axes[1],kind='barh')#axes[1]为第二个子图
"""
<AxesSubplot:>
"""


指定绘图的种类,例如条形图、散点图等

df = pd.DataFrame(np.random.rand(6,4),index=['one','two','three','four','five','six'],columns=pd.Index(['A','B','C','D'],name='Beyond'))
df

df.plot(kind='bar')
"""
<AxesSubplot:>
"""


macrodata.csv下载链接

macro = pd.read_csv('macrodata.csv')
macro.plot.scatter('quarter','realgdp')
"""
<AxesSubplot:xlabel='quarter', ylabel='realgdp'>
"""

四、大数据处理技巧

game_logs.csv数据集下载

Ⅰ,数值类型转换

读取一个稍大数据集,特征比较多,一共有161列,目标就是尽可能减少占用的内存

gl = pd.read_csv('game_logs.csv')
gl.head()


数据样本有171907个

gl.shape
"""
(171907, 161)
"""

deep表示要详细的展示当前数据所占用的内存
输出结果显示这份数据读取进来后占用859.4 MB内存,数据类型主要有3种
float64类型有77个特征,int64类型有6个特征,object类型有78个特征

gl.info(memory_usage='deep')
"""
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 171907 entries, 0 to 171906
Columns: 161 entries, date to acquisition_info
dtypes: float64(77), int64(6), object(78)
memory usage: 859.4 MB
"""

计算一下各种类型平均占用内存
循环中会遍历3种类型,通过select_dtypes()函数选中属于当前类型的特征
计算其平均占用内存,最后转换成MB
很显然,float64类型和int64类型平均占用内存差不多,object类型占用的内存最多

for dtype in ['float64','int64','object']:selected_dtype = gl.select_dtypes(include=[dtype])mean_usage_b = selected_dtype.memory_usage(deep=True).mean()mean_usage_mb = mean_usage_b/1024**2print('avg memory:',dtype,mean_usage_mb)
"""
avg memory: float64 1.294733194204477
avg memory: int64 1.1242000034877233
avg memory: object 9.500870656363572
"""

接着,需要分类型对数据进行处理
首先处理一下数值型

输出结果分别打印了int8~int64可以表示的数值取值范围
int8和int16能表示的数值范围有点儿小,一般不用
int32看起来范围足够大了,基本任务都能满足
int64能表示的就更多了

int_types = ['int8','int16','int32','int64']
for it in int_types:print(np.iinfo(it))
"""
Machine parameters for int8
---------------------------------------------------------------
min = -128
max = 127
---------------------------------------------------------------Machine parameters for int16
---------------------------------------------------------------
min = -32768
max = 32767
---------------------------------------------------------------Machine parameters for int32
---------------------------------------------------------------
min = -2147483648
max = 2147483647
---------------------------------------------------------------Machine parameters for int64
---------------------------------------------------------------
min = -9223372036854775808
max = 9223372036854775807
---------------------------------------------------------------
"""

将数据集中所有int64类型转换成int32类型

def mem_usage(pandas_obj):if isinstance(pandas_obj,pd.DataFrame):#计算DataFrame和Series类型数据,如果包含多列就求其总和,如果只有一列,那就是它自身usage_b = pandas_obj.memory_usage(deep=True).sum()else:usage_b = pandas_obj.memory_usage(deep=True)usage_mb = usage_b/1024**2return '{:03.2f} MB'.format(usage_mb)gl_int = gl.select_dtypes(include=['int64'])#select_dtypes(include=['int64'])表示此时要处理的是全部int64格式数据
coverted_int = gl_int.apply(pd.to_numeric,downcast='integer')#进行向下转换
gl_int

coverted_int


数据集所有数据类型都转换为int64时,int类型数据所占内存空间为7.87MB
向下转换之后,程序已经自动地选择了合适类型,int类型数据内存占有量为1.80MB
其中mem_usage()函数的主要功能就是计算传入数据的内存占用量

print(mem_usage(gl_int))
print(mem_usage(coverted_int))
"""
7.87 MB
1.80 MB
"""

向下转换程序已经自动地选择了合适类型
所有数据类型都转换为float64时,float类型数据内存占用100.99MB
向下转换之后,float类型数据内存占有量为50.49MB
内存节约了正好一半
通常在数据集中float类型多一些,如果对其进行合适的向下转换,基本上能节省一半内存

gl_float = gl.select_dtypes(include=['float64'])
converted_float = gl_float.apply(pd.to_numeric,downcast='float')
print(mem_usage(gl_float))
print(mem_usage(converted_float))
"""
100.99 MB
50.49 MB
"""

Ⅱ,属性类型转换

object类型(字符串)占用内存最多,各列object类型的特征如下
count表示数据中每一列特征的样本个数(有些存在缺失值)
unique表示不同属性值的个数(例如day_of_week列表示当前数据是星期几,所以只有7个不同的值;但是默认object类型会把出现的每一条样本数值都开辟一块内存区域,若星期一和星期二出现多次,它们只是一个字符串代表一种结果而已,共用一块内存就足够了。但是在object类型中却为每一条数据开辟了单独的一块内存)

故可以把object类型转换成category类型

gl_obj = gl.select_dtypes(include=['object']).copy()
gl_obj.describe()


把object类型转换成category类型
其中只有7种编码方式

dow = gl_obj.day_of_week
dow_cat = dow.astype('category')
dow_cat.head()
"""
0    Thu
1    Fri
2    Sat
3    Mon
4    Tue
Name: day_of_week, dtype: category
Categories (7, object): ['Fri', 'Mon', 'Sat', 'Sun', 'Thu', 'Tue', 'Wed']
"""

打印具体编码
无论打印多少条数据,其编码结果都不会超过7种,这就是category类型的特性

dow_cat.head(10).cat.codes
"""
0    4
1    0
2    2
3    1
4    5
5    4
6    2
7    2
8    1
9    5
dtype: int8
"""

将object类型转换成category类型,看下所占用内存空间情况

print(mem_usage(dow))
print(mem_usage(dow_cat))
"""
9.84 MB
0.16 MB
"""
converted_obj = pd.DataFrame()for col in gl_obj.columns:num_unique_values = len(gl_obj[col].unique())num_total_values = len(gl_obj[col])if num_unique_values / num_total_values < 0.5:#对object类型数据中唯一值个数进行判断,如果数量不足整体的一半(此时能共用的内存较多),就执行转换操作,如果唯一值过多,就没有必要执行此操作。converted_obj.loc[:,col] = gl_obj[col].astype('category')else:converted_obj.loc[:,col] = gl_obj[col]print(mem_usage(gl_obj))
print(mem_usage(converted_obj))
"""
750.57 MB
51.67 MB
"""

Pandas(数据分析处理库)---讲解相关推荐

  1. 图解数据分析(12) | Pandas - 数据分析工具库介绍(数据科学家入门·完结)

    作者:韩信子@ShowMeAI 教程地址:https://www.showmeai.tech/tutorials/33 本文地址:https://www.showmeai.tech/article-d ...

  2. 【A-003】python数据分析与机器学习实战 Python科学计算库 Pandas数据分析处理库(二)

    目录: 处理缺失数据制作透视图删除含空数据的行和列多行索引使用apply函数 本节要处理的数据来自于泰坦尼克号的生存者名单,它的数据如下: PassengerId Survived Pclass .. ...

  3. 数据分析处理库-Pandas

    Pandas (数据分析处理库) Pandas:纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具.提供了大量能使我们快速便捷地处理数据的函数和方法. 1.Pandas数据读取 1 ...

  4. Pandas数据分析库(2)Python数据分析

    1 pandas简介 Python在数据处理和准备方面一直做得很好,但在数据分析和建模方面就差一些.pandas帮助填补了这一空白,使您能够在Python中执行整个数据分析工作流程,而不必切换到更特定 ...

  5. 鸽子学Python 之 Pandas数据分析库

    本文来自鸽子学Python专栏系列文章,欢迎各位交流. 文章目录 Pandas介绍 第一部分 Pandas基础 1 Pandas数据结构 1.1 Series 1.2 DataFrame 2 数据查看 ...

  6. CC00038.python——|HadoopPython.v02|——|Arithmetic.v02|Pandas数据分析库:Pandas数据结构|

    一.pandas数据分析库 ### --- pandas数据分析库~~~ Python在数据处理和准备⽅⾯⼀直做得很好,但在数据分析和建模⽅⾯就差⼀些. ~~~ pandas帮助填补了这⼀空⽩,使您能 ...

  7. Python基础入门 (四数据分析处理库Pandas应用)

    1.Pandas简介 2.两种数据结构 3.相关操作(索引,查询,统计分析,SQL操作,对缺失值处理,excel的数据透视表功能,多层索引) 1.Pandas简介 Pandas是基于Numpy的一个开 ...

  8. AI常用框架和工具丨2. 数据分析处理库Pandas

    数据分析处理库Pandas,AI常用框架和工具之一.理论知识结合代码实例,希望对您有所帮助. 文章目录 环境说明 一.Pandas简介 二. Pandas中的数据结构 2.1 Series 2.2 D ...

  9. html数据分析表格api_Python数据分析基本库——Matplotlib(一)

    1. Matplotlib基础:https://www.runoob.com/numpy/numpy-matplotlib.html2. Matplotlib官网:https://matplotlib ...

  10. numpy随机生成01矩阵_Python数据分析Numpy库常用函数详解,提到循环就该想到的库...

    Python进行数据分析的核心库肯定是Pandas,该库差不多可以解决结构化数据的绝大部分处理需求.在<Python数据分析常用函数及参数详解,可以留着以备不时之需 >一文中也已经对该库的 ...

最新文章

  1. 概述HTML文档的基本结构,HTML概述与基本结构
  2. 文本编辑器实现文本打印的功能
  3. iOS10 UI教程层次结构的事件
  4. 博客统计:腾讯分析这些数据哪儿来的?
  5. opencv4 图像特征匹配_概述 | 全景图像拼接技术全解析
  6. python 解小学数学题_孩子尝试python解数学题,怎么实现呢?
  7. android序列化好处,浅谈Android序列化
  8. vSAN6.2 性能服务
  9. 高性能日记--show profile剖析sql语句
  10. 第4章 最基础的分类算法-k近邻算法 kNN 学习笔记 中
  11. android 获取url 参数值
  12. 【个人笔记】Ubuntu18.04 安装显卡驱动
  13. 如何做一个能赚钱的技术公众号?
  14. 防Ddos文献之应对篇-DDoS防御方案
  15. rtmp/rtsp测试地址 2019/11/22日亲测可用
  16. windows xp 驱动开发(十八) USB驱动程序开发用到的工具总结
  17. 强大的接口测试与压力测试工具——postmanjmeter
  18. Android APP性能分析工具大全
  19. AGM FPGA使用答疑
  20. 篮球数据API接口 - 【篮球文字直播】API调用示例代码

热门文章

  1. IOS OC UIKit基本使用
  2. 路由器静态路由配置实验
  3. 票务公司加价将儿童机票售成年人赚取差价
  4. 浅谈什么是大数据?大数据可以做什么?
  5. 微信 PC(电脑端) 多开批处理
  6. 基于Verilog HDL的数字秒表
  7. Spring Boot优点和缺点
  8. Factorization Machines 论文翻译
  9. MariaDB 10.6.10离线安装
  10. Linux安装mariaDB以及修改Mariadb存储路径