pandas基础

pandas基础

pandas介绍

Python Data Analysis Library

pandas是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。Pandas 纳入 了大量库和一些标准的数据模型,提供了高效地操作大型结构化数据集所需的工具。

pandas核心数据结构

数据结构是计算机存储、组织数据的方式。 通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技术有关。

Series

Series可以理解为一个一维的数组,只是index名称可以自己改动。类似于定长的有序字典,有Index和 value。

import pandas as pd
import numpy as np

# 创建一个空的系列
s = pd.Series() #Series([], dtype: float64)
# 从ndarray创建一个系列
data=np.array(["校长","处长","厅长","部长"])
s=pd.Series(data) 
#结果如下:
    0    校长
    1    处长
    2    厅长
    3    部长
	dtype: object
s = pd.Series(data,index=[100,101,102,103])
#输出结果:
	100    校长
    101    处长
    102    厅长
    103    部长
    dtype: object
# 从字典创建一个系列(存储的是值)	
data = {'a' : 0., 'b' : 1., 'c' : 2.}
s = pd.Series(data)
#ps:
	a    0.0
    b    1.0
    c    2.0
    dtype: float64
# 从标量创建一个系列
s = pd.Series(5, index=[0, 1, 2, 3])
#ps:
	0    5
    1    5
    2    5
    3    5
    dtype: int64

访问Series中的数据:

# 使用索引检索元素
s = pd.Series([1,2,3,4,5],index = ['a','b','c','d','e'])
print(s[0])   #ps: 1
print(s[:3])
#ps: 
	a    1
    b    2
    c    3
    dtype: int64
print(s[-3:])
#ps:
	c    3
    d    4
    e    5
    dtype: int64
print(s["a"],s["b"])
#ps:	
	1 2
print(s[["c","d","e"]])
#ps:
	c    3
    d    4
    e    5
    dtype: int64

# 使用标签检索数据
print(s['a'], s[['a','c','d']])

pandas日期处理

# pandas识别的日期字符串格式
dates = pd.Series(['2011', '2011-02', '2011-03-01', '2011/04/01','2011/05/01 01:01:01', '01 Jun 2011'])
# to_datetime() 转换日期数据类型
dates = pd.to_datetime(dates)
print(dates)
#ps:
	0   2011-01-01 00:00:00
    1   2011-02-01 00:00:00
    2   2011-03-01 00:00:00
    3   2011-04-01 00:00:00
    4   2011-05-01 01:01:01
    5   2011-06-01 00:00:00
    dtype: datetime64[ns]
print(dates.dtype,type(dates))
#ps:
	datetime64[ns] <class 'pandas.core.series.Series'>
# datetime类型数据支持日期运算
delta = dates - pd.to_datetime('1970-01-01')
print(delta)
#ps:
	0   15218 days 00:00:00
    1   15006 days 00:00:00
    2   15034 days 00:00:00
    3   15065 days 00:00:00
    4   15095 days 01:01:01
    5   15126 days 00:00:00
    dtype: timedelta64[ns]
# 获取天数数值
print(delta.dt.days)

Series.dt提供了很多日期相关操作,如下:

Series.dt.year	The year of the datetime.
Series.dt.month	The month as January=1, December=12.
Series.dt.day	The days of the datetime.
Series.dt.hour	The hours of the datetime.
Series.dt.minute	The minutes of the datetime.
Series.dt.second	The seconds of the datetime.
Series.dt.microsecond	The microseconds of the datetime.
Series.dt.week	The week ordinal of the year.
Series.dt.weekofyear	The week ordinal of the year.
Series.dt.dayofweek	The day of the week with Monday=0, Sunday=6.
Series.dt.weekday	The day of the week with Monday=0, Sunday=6.
Series.dt.dayofyear	The ordinal day of the year.
Series.dt.quarter	The quarter of the date.
Series.dt.is_month_start	Indicates whether the date is the first day of the month.
Series.dt.is_month_end	Indicates whether the date is the last day of the month.
Series.dt.is_quarter_start	Indicator for whether the date is the first day of a quarter.
Series.dt.is_quarter_end	Indicator for whether the date is the last day of a quarter.
Series.dt.is_year_start	Indicate whether the date is the first day of a year.
Series.dt.is_year_end	Indicate whether the date is the last day of the year.
Series.dt.is_leap_year	Boolean indicator if the date belongs to a leap year.
Series.dt.days_in_month	The number of days in the month.
DateTimeIndex

通过指定周期和频率,使用date_range()函数就可以创建日期序列。 默认情况下,范围的频率是天。

import pandas as pd
# 以日为频率(periods:生成日期数量)
datelist = pd.date_range('2019/08/21', periods=5)
print(datelist)
#ps:
    DatetimeIndex(['2019-08-21', '2019-08-22', '2019-08-23', '2019-08-24','2019-08-25'],dtype='datetime64[ns]', freq='D')
# 以月为频率
datelist = pd.date_range('2019/08/21', periods=5,freq='M')
print(datelist)
#ps:
	DatetimeIndex(['2019-08-31', '2019-09-30', '2019-10-31', '2019-11-30','2019-12-31'], dtype='datetime64[ns]',freq='M')
# 构建某个区间的时间序列
start = pd.datetime(2017, 11, 1)
end = pd.datetime(2017, 11, 5)
dates = pd.date_range(start, end)
print(dates)
#ps:
	DatetimeIndex(['2017-11-01', '2017-11-02', '2017-11-03', '2017-11-04','2017-11-05'], dtype='datetime64[ns]',freq='D')

bdate_range()用来表示商业日期范围,不同于date_range(),它不包括星期六和星期天。

import pandas as pd
datelist = pd.bdate_range('2011/11/03', periods=5)
print(datelist)
#ps:
	DatetimeIndex(['2011-11-03', '2011-11-04', '2011-11-07', '2011-11-08','2011-11-09'],dtype='datetime64[ns]', freq='B')
DataFrame

DataFrame是一个类似于表格的数据类型,可以理解为一个二维数组,索引有两个维度,可更改。DataFrame具有以下特点:

  • 潜在的列是不同的类型
  • 大小可变
  • 标记轴(行和列)
  • 可以对行和列执行算术运算
import pandas as pd

# 创建一个空的DataFrame
df = pd.DataFrame()
print(df)

# 从列表创建DataFrame
data=[80,90,70,87]
df=pd.DataFrame(data)
print(df)
#ps:
	    0
    0  80
    1  90
    2  70
    3  87
data=[["Tom",80],["Isrry",90],["lilei",20]]
df=pd.DataFrame(data,index=["101","102","103"],columns=["name","score"])
print(df)
#ps:
	      name  score
    101    Tom     80
    102  Isrry     90
    103  lilei     20
data = [['Alex',10],['Bob',12],['Clarke',13]]
df = pd.DataFrame(data,columns=['Name','Age'],dtype=float)
print(df)
data = [{'a': 1, 'b': 2},{'a': 5, 'b': 10, 'c': 20}]
df = pd.DataFrame(data)
print(df)
#ps:
	   a   b     c
    0  1   2   NaN
    1  5  10  20.0
data = [{'p': 1, 'q': 2},{'a': 5, 'b': 10, 'c': 20}]
df = pd.DataFrame(data)
print(df)
#ps:
	     a     b     c    p    q
    0  NaN   NaN   NaN  1.0  2.0
    1  5.0  10.0  20.0  NaN  NaN
# 从字典来创建DataFrame
data = {'Name':['Tom', 'Jack', 'Steve', 'Ricky'],'Age':[28,34,29,42]}
df = pd.DataFrame(data, index=['s1','s2','s3','s4'])
print(df)
#ps:
	     Name  Age
    s1    Tom   28
    s2   Jack   34
    s3  Steve   29
    s4  Ricky   42
data = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']),
        'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])}
df = pd.DataFrame(data)
print(df)
#ps:
	   one  two
    a  1.0    1
    b  2.0    2
    c  3.0    3
    d  NaN    4
核心数据结构操作

列访问

DataFrame的单列数据为一个Series。根据DataFrame的定义可以 知晓DataFrame是一个带有标签的二维数组,每个标签相当每一列的列名。

import pandas as pd

d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']),
     'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])}

df = pd.DataFrame(d)
print(df['one'])
print(df[['one', 'two']])

列添加

DataFrame添加一列的方法非常简单,只需要新建一个列索引。并对该索引下的数据进行赋值操作即可。

import pandas as pd

data = {'Name':['Tom', 'Jack', 'Steve', 'Ricky'],'Age':[28,34,29,42]}
df = pd.DataFrame(data, index=['s1','s2','s3','s4'])
df['score']=pd.Series([90, 80, 70, 60], index=['s1','s2','s3','s4'])
print(df)

列删除

删除某列数据需要用到pandas提供的方法pop,pop方法的用法如下:

import pandas as pd

d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']), 
     'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd']), 
     'three' : pd.Series([10, 20, 30], index=['a', 'b', 'c'])}
df = pd.DataFrame(d)
print("dataframe is:")
print(df)

# 删除一列: one
del(df['one'])
print(df)

#调用pop方法删除一列
df.pop('two')
print(df)

行访问

如果只是需要访问DataFrame某几行数据的实现方式则采用数组的选取方式,使用 “:” 即可:

import pandas as pd

d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']), 
    'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])}

df = pd.DataFrame(d)
print(df[2:4])

loc方法是针对DataFrame索引名称的切片方法。loc方法使用方法如下:

import pandas as pd

d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']), 
     'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])}

df = pd.DataFrame(d)
print(df.loc['b'])
print(df.loc[['a', 'b']])

iloc和loc区别是iloc接收的必须是行索引和列索引的位置。iloc方法的使用方法如下:

import pandas as pd

d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']),
     'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])}

df = pd.DataFrame(d)
print(df.iloc[2])
print(df.iloc[[2, 3]])

行添加

import pandas as pd

df = pd.DataFrame([['zs', 12], ['ls', 4]], columns = ['Name','Age'])
df2 = pd.DataFrame([['ww', 16], ['zl', 8]], columns = ['Name','Age'])

df = df.append(df2)
print(df)

行删除

使用索引标签从DataFrame中删除或删除行。 如果标签重复,则会删除多行。

import pandas as pd

df = pd.DataFrame([['zs', 12], ['ls', 4]], columns = ['Name','Age'])
df2 = pd.DataFrame([['ww', 16], ['zl', 8]], columns = ['Name','Age'])
df = df.append(df2)
# 删除index为0的行
df = df.drop(0)
print(df)

修改DataFrame中的数据

更改DataFrame中的数据,原理是将这部分数据提取出来,重新赋值为新的数据。

import pandas as pd

df = pd.DataFrame([['zs', 12], ['ls', 4]], columns = ['Name','Age'])
df2 = pd.DataFrame([['ww', 16], ['zl', 8]], columns = ['Name','Age'])
df = df.append(df2)
df['Name'][0] = 'Tom'
print(df)

#行修改(具体某一列)
df["Age"]=20
print(df)
#具体数值
df["Age"]["s2"]=50
print(df)

DataFrame常用属性

编号属性或方法描述
1axes返回 行/列 标签(index)列表。
2dtype返回对象的数据类型(dtype)。
3empty如果系列为空,则返回True
4ndim返回底层数据的维数,默认定义:1
5size返回基础数据中的元素数。
6values将系列作为ndarray返回。
7head()返回前n行。
8tail()返回最后n行。

实例代码:

import pandas as pd

data = {'Name':['Tom', 'Jack', 'Steve', 'Ricky'],'Age':[28,34,29,42]}
df = pd.DataFrame(data, index=['s1','s2','s3','s4'])
df['score']=pd.Series([90, 80, 70, 60], index=['s1','s2','s3','s4'])
print(df)
print(df.axes)
print(df['Age'].dtype)
print(df.empty)
print(df.ndim)
print(df.size)
print(df.values)
print(df.head(3)) # df的前三行
print(df.tail(3)) # df的后三行

Jupyter notebook

Jupyter Notebook(此前被称为 IPython notebook)是一个交互式笔记本,支持运行 40 多种编程语言。使用浏览器作为界面,向后台的IPython服务器发送请求,并显示结果。 Jupyter Notebook 的本质是一个 Web 应用程序,便于创建和共享文学化程序文档,支持实时代码,数学方程,可视化和 markdown。

IPython 是一个 python 的交互式 shell,比默认的python shell 好用得多,支持变量自动补全,自动缩进,支持 bash shell 命令,内置了许多很有用的功能和函数。

安装ipython

windows: 前提是有numpy,matplotlib pandas

​ 采用pip安装 pip install ipython

OS X: AppStore下载安装苹果开发工具Xcode。

​ 使用easy_install或pip安装IPython,或者从源文件安装。

安装Jupyter notebook

pip3 install jupyter

启动jupyter notebook

在文件目录中打开终端,输入:jupyter notebook

pandas核心

pandas描述性统计

数值型数据的描述性统计主要包括了计算数值型数据的完整情况、最小值、均值、中位 数、最大值、四分位数、极差、标准差、方差、协方差等。在NumPy库中一些常用的统计学函数也可用于对数据框进行描述性统计。

np.min	最小值 
np.max	最大值 
np.mean	均值 
np.ptp	极差 
np.median	中位数 
np.std	标准差 
np.var	方差 
np.cov	协方差

实例:

import pandas as pd
import numpy as np

# 创建DF
d = {'Name':pd.Series(['Tom','James','Ricky','Vin','Steve','Minsu','Jack','Lee','David','Gasper','Betina','Andres']),
 'Age':pd.Series([25,26,25,23,30,29,23,34,40,30,51,46]),
'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8,3.78,2.98,4.80,4.10,3.65])}
df = pd.DataFrame(d)
print(df)
# 测试描述性统计函数
print(df.sum())
print(df.sum(1))  #1:轴向(axis)    水平求和
print(df.mean())
print(df.mean(1))

pandas提供了统计相关函数:

1count()非空观测数量
2sum()所有值之和
3mean()所有值的平均值
4median()所有值的中位数
5std()值的标准偏差
6min()所有值中的最小值
7max()所有值中的最大值
8abs()绝对值
9prod()数组元素的乘积
10cumsum()累计总和
11cumprod()累计乘积
12info()所有列的基本信息

pandas还提供了一个方法叫作describe,能够一次性得出数据框所有数值型特征的非空值数目、均值、标准差等。

import pandas as pd
import numpy as np

#Create a Dictionary of series
d = {'Name':pd.Series(['Tom','James','Ricky','Vin','Steve','Minsu','Jack',
   'Lee','David','Gasper','Betina','Andres']),
   'Age':pd.Series([25,26,25,23,30,29,23,34,40,30,51,46]),
   'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8,3.78,2.98,4.80,4.10,3.65])}

#Create a DataFrame
df = pd.DataFrame(d)
print(df.describe())  #描述基本数据统计
#ps:
	             Age     Rating
        count  12.000000  12.000000
        mean   31.833333   3.743333
        std     9.232682   0.661628
        min    23.000000   2.560000
        25%    25.000000   3.230000
        50%    29.500000   3.790000
        75%    35.500000   4.132500
        max    51.000000   4.800000
print(df.describe(include=['object']))
#ps:
	          Name
    count       12
    unique      12
    top     Gasper
    freq         1
print(df.describe(include=['number'])) #默认 
print(df.describe(include=['object']))
#ps:
	          Name        Age     Rating
    count       12  12.000000  12.000000
    unique      12        NaN        NaN
    top     Gasper        NaN        NaN
    freq         1        NaN        NaN
    mean       NaN  31.833333   3.743333
    std        NaN   9.232682   0.661628
    min        NaN  23.000000   2.560000
    25%        NaN  25.000000   3.230000
    50%        NaN  29.500000   3.790000
    75%        NaN  35.500000   4.132500
    max        NaN  51.000000   4.800000

pandas排序

Pandas有两种排序方式,它们分别是按标签与按实际值排序。

import pandas as pd
import numpy as np

unsorted_df=pd.DataFrame(np.random.randn(10,2),
                      	index=[1,4,6,2,3,5,9,8,0,7],
                       	columns=['col2','col1'])
print(unsorted_df)

按行标签排序

使用sort_index()方法,通过传递axis参数和排序顺序,可以对DataFrame进行排序。 默认情况下,按照升序对行标签进行排序。

import pandas as pd
import numpy as np

d = {'Name':pd.Series(['Tom','James','Ricky','Vin','Steve','Minsu','Jack',
   'Lee','David','Gasper','Betina','Andres']),
   'Age':pd.Series([25,26,25,23,30,29,23,34,40,30,51,46]),
   'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8,3.78,2.98,4.80,4.10,3.65])}
unsorted_df = pd.DataFrame(d)
# 按照行标进行排序
sorted_df=unsorted_df.sort_index()
print (sorted_df)
#      Name  Age  Rating
0      Tom   25    4.23
1    James   26    3.24
2    Ricky   25    3.98
3      Vin   23    2.56
4    Steve   30    3.20
5    Minsu   29    4.60
6     Jack   23    3.80
7      Lee   34    3.78
8    David   40    2.98
9   Gasper   30    4.80
10  Betina   51    4.10
11  Andres   46    3.65
# 控制排序顺序
sorted_df = unsorted_df.sort_index(ascending=False)
print (sorted_df)
#      Name  Age  Rating
11  Andres   46    3.65
10  Betina   51    4.10
9   Gasper   30    4.80
8    David   40    2.98
7      Lee   34    3.78
6     Jack   23    3.80
5    Minsu   29    4.60
4    Steve   30    3.20
3      Vin   23    2.56
2    Ricky   25    3.98
1    James   26    3.24
0      Tom   25    4.23

按列标签排序

import numpy as np

d = {'Name':pd.Series(['Tom','James','Ricky','Vin','Steve','Minsu','Jack',
   'Lee','David','Gasper','Betina','Andres']),
   'Age':pd.Series([25,26,25,23,30,29,23,34,40,30,51,46]),
   'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8,3.78,2.98,4.80,4.10,3.65])}
unsorted_df = pd.DataFrame(d)
# 按照列标签进行排序
sorted_df=unsorted_df.sort_index(axis=1)
print (sorted_df)
#    Age    Name  Rating
0    25     Tom    4.23
1    26   James    3.24
2    25   Ricky    3.98
3    23     Vin    2.56
4    30   Steve    3.20
5    29   Minsu    4.60
6    23    Jack    3.80
7    34     Lee    3.78
8    40   David    2.98
9    30  Gasper    4.80
10   51  Betina    4.10
11   46  Andres    3.65

按某列值排序

像索引排序一样,sort_values()是按值排序的方法。它接受一个by参数,它将使用要与其排序值的DataFrame的列名称。

import pandas as pd
import numpy as np

d = {'Name':pd.Series(['Tom','James','Ricky','Vin','Steve','Minsu','Jack',
   'Lee','David','Gasper','Betina','Andres']),
   'Age':pd.Series([25,26,25,23,30,29,23,34,40,30,51,46]),
   'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8,3.78,2.98,4.80,4.10,3.65])}
unsorted_df = pd.DataFrame(d)
# 按照年龄进行排序
sorted_df = unsorted_df.sort_values(by='Age')
print (sorted_df)
#      Name  Age  Rating
3      Vin   23    2.56
6     Jack   23    3.80
0      Tom   25    4.23
2    Ricky   25    3.98
1    James   26    3.24
5    Minsu   29    4.60
4    Steve   30    3.20
9   Gasper   30    4.80
7      Lee   34    3.78
8    David   40    2.98
11  Andres   46    3.65
10  Betina   51    4.10
# 先按Age进行升序排序,然后按Rating降序排序
sorted_df = unsorted_df.sort_values(by=['Age', 'Rating'], ascending=[True, False])
print (sorted_df)
#      Name  Age  Rating
6     Jack   23    3.80
3      Vin   23    2.56
0      Tom   25    4.23
2    Ricky   25    3.98
1    James   26    3.24
5    Minsu   29    4.60
9   Gasper   30    4.80
4    Steve   30    3.20
7      Lee   34    3.78
8    David   40    2.98
11  Andres   46    3.65
10  Betina   51    4.10

pandas分组

在许多情况下,我们将数据分成多个集合,并在每个子集上应用一些函数。在应用函数中,可以执行以下操作 :

  • 聚合 - 计算汇总统计
  • 转换 - 执行一些特定于组的操作
  • 过滤 - 在某些情况下丢弃数据
import pandas as pd

ipl_data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings','kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],
         'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],
         'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],
         'Points':[876,789,863,673,741,812,756,788,694,701,804,690]}
df = pd.DataFrame(ipl_data)
print(df)
#      Team  Rank  Year  Points
0   Riders     1  2014     876
1   Riders     2  2015     789
2   Devils     2  2014     863
3   Devils     3  2015     673
4    Kings     3  2014     741
5    kings     4  2015     812
6    Kings     1  2016     756
7    Kings     1  2017     788
8   Riders     2  2016     694
9   Royals     4  2014     701
10  Royals     1  2015     804
11  Riders     2  2017     690
将数据拆分成组
# 按照年份Year字段分组
print (df.groupby('Year'))
#<pandas.core.groupby.generic.DataFrameGroupBy object at 0x7f9c6c651908>
# 查看分组结果
print (df.groupby('Year').groups)
#ps:
	{2014: Int64Index([0, 2, 4, 9], dtype='int64'), 2015: Int64Index([1, 3, 5, 10], dtype='int64'), 2016: Int64Index([6, 8], dtype='int64'), 2017: Int64Index([7, 11], dtype='int64')}
迭代遍历分组

groupby返回可迭代对象,可以使用for循环遍历:

grouped = df.groupby('Year')
# 遍历每个分组
for year,group in grouped:
    print (year)
    print (group)
#ps:
	2014
         Team  Rank  Year  Points
    0  Riders     1  2014     876
    2  Devils     2  2014     863
    4   Kings     3  2014     741
    9  Royals     4  2014     701
    2015
          Team  Rank  Year  Points
    1   Riders     2  2015     789
    3   Devils     3  2015     673
    5    kings     4  2015     812
    10  Royals     1  2015     804
    2016
         Team  Rank  Year  Points
    6   Kings     1  2016     756
    8  Riders     2  2016     694
    2017
          Team  Rank  Year  Points
    7    Kings     1  2017     788
    11  Riders     2  2017     690
获得一个分组细节
grouped = df.groupby('Year')
print (grouped.get_group(2014))
#ps:
	     Team  Rank  Year  Points
    0  Riders     1  2014     876
    2  Devils     2  2014     863
    4   Kings     3  2014     741
    9  Royals     4  2014     701
分组聚合

聚合函数为每个组返回聚合值。当创建了分组(group by)对象,就可以对每个分组数据执行求和、求标准差等操作。

# 聚合每一年的平均的分
grouped = df.groupby('Year')
print (grouped['Points'].agg(np.mean))
print(data.groupby("Year").agg({"Points":np.mean}))
#ps:
	Year
    2014    795.25
    2015    769.50
    2016    725.00
    2017    739.00
    Name: Points, dtype: float64
# 聚合每一年的分数之和、平均分、标准差
grouped = df.groupby('Year')
agg = grouped['Points'].agg([np.sum, np.mean, np.std])
print (agg)
#ps:
	       sum    mean        std
    Year                         
    2014  3181  795.25  87.439026
    2015  3078  769.50  65.035888
    2016  1450  725.00  43.840620
    2017  1478  739.00  69.296465

pandas数据表关联操作

Pandas具有功能全面的高性能内存中连接操作,与SQL等关系数据库非常相似。
Pandas提供了一个单独的merge()函数,作为DataFrame对象之间所有标准数据库连接操作的入口。

合并两个DataFrame:

import pandas as pd
left = pd.DataFrame({
         'student_id':[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],
         'student_name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung', 'Billy', 'Brian', 'Bran', 'Bryce', 'Betty', 'Emma', 'Marry', 'Allen', 'Jean', 'Rose', 'David', 'Tom', 'Jack', 'Daniel', 'Andrew'],
         'class_id':[1,1,1,2,2,2,3,3,3,4,1,1,1,2,2,2,3,3,3,2], 
         'gender':['M', 'M', 'F', 'F', 'M', 'M', 'F', 'F', 'M', 'M', 'F', 'F', 'M', 'M', 'F', 'F', 'M', 'M', 'F', 'F'], 
         'age':[20,21,22,20,21,22,23,20,21,22,20,21,22,23,20,21,22,20,21,22], 
         'score':[98,74,67,38,65,29,32,34,85,64,52,38,26,89,68,46,32,78,79,87]})
right = pd.DataFrame(
         {'class_id':[1,2,3,5],
         'class_name': ['ClassA', 'ClassB', 'ClassC', 'ClassE']})
# 合并两个DataFrame
data = pd.merge(left,right)
print(data)

使用“how”参数合并DataFrame:

# 合并两个DataFrame (左连接)
rs = pd.merge(left, right, how='left')
print(rs)

其他合并方法同数据库相同:

合并方法SQL等效描述
leftLEFT OUTER JOIN使用左侧对象的键
rightRIGHT OUTER JOIN使用右侧对象的键
outerFULL OUTER JOIN使用键的联合
innerINNER JOIN使用键的交集

试验:

# 合并两个DataFrame (左连接)
rs = pd.merge(left,right,on='subject_id', how='right')
print(rs)
# 合并两个DataFrame (联合连接)
rs = pd.merge(left,right,on='subject_id', how='outer')
print(rs)
# 合并两个DataFrame (集合连接)
rs = pd.merge(left,right,on='subject_id', how='inner')
print(rs)

pandas透视表与交叉表

有如下数据:

import pandas as pd
left = pd.DataFrame({
         'student_id':[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],
         'student_name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung', 'Billy', 'Brian', 'Bran', 'Bryce', 'Betty', 'Emma', 'Marry', 'Allen', 'Jean', 'Rose', 'David', 'Tom', 'Jack', 'Daniel', 'Andrew'],
         'class_id':[1,1,1,2,2,2,3,3,3,4,1,1,1,2,2,2,3,3,3,2], 
         'gender':['M', 'M', 'F', 'F', 'M', 'M', 'F', 'F', 'M', 'M', 'F', 'F', 'M', 'M', 'F', 'F', 'M', 'M', 'F', 'F'], 
         'age':[20,21,22,20,21,22,23,20,21,22,20,21,22,23,20,21,22,20,21,22], 
         'score':[98,74,67,38,65,29,32,34,85,64,52,38,26,89,68,46,32,78,79,87]})
right = pd.DataFrame(
         {'class_id':[1,2,3,5],
         'class_name': ['ClassA', 'ClassB', 'ClassC', 'ClassE']})
# 合并两个DataFrame
data = pd.merge(left,right)
print(data)

透视表

透视表(pivot table)是各种电子表格程序和其他数据分析软件中一种常见的数据汇总工具。它根据一个或多个键对数据进行分组聚合,并根据每个分组进行数据汇总

# 以class_id与gender做分组汇总数据,默认聚合统计所有列
print(data.pivot_table(index=['class_id', 'gender']))

# 以class_id与gender做分组汇总数据,聚合统计score列
print(data.pivot_table(index=['class_id', 'gender'], values=['score']))

# 以class_id与gender做分组汇总数据,聚合统计score列,针对age的每个值列级分组统计
print(data.pivot_table(index=['class_id', 'gender'], values=['score'],columns=['age']))
#ps:
	                score                  
    age                20    21    22    23
    class_id gender                        
    1        F       52.0  38.0  67.0   NaN
             M       98.0  74.0  26.0   NaN
    2        F       53.0  46.0  87.0   NaN
             M        NaN  65.0  29.0  89.0
    3        F       34.0  79.0   NaN  32.0
             M       78.0  85.0  32.0   NaN
# 以class_id与gender以及age做分组汇总数据,聚合统计score列
print(data.pivot_table(index=['class_id', 'gender',"age"], values=['score']))
#ps:
	                     score
    class_id gender age       
    1        F      20      52
                    21      38
                    22      67
             M      20      98
                    21      74
                    22      26
    2        F      20      53
                    21      46
                    22      87
             M      21      65
                    22      29
                    23      89
    3        F      20      34
                    21      79
                    23      32
             M      20      78
                    21      85
                    22      32

# 以class_id与gender做分组汇总数据,聚合统计score列,针对age的每个值列级分组统计,添加行、列小计
print(data.pivot_table(index=['class_id', 'gender'], values=['score'], columns=['age'], margins=True))  #(均值)
#ps:
	                     score                             
age   class_id gender   20    21    22    23     All   
                                       
1        F       	52.000000  38.0  67.0   NaN  52.333333
         M       	98.000000  74.0  26.0   NaN  66.000000
2        F       	53.000000  46.0  87.0   NaN  59.750000
         M             NaN  	65.0  29.0  89.0  61.000000
3        F      	 34.000000  79.0   NaN  32.0  48.333333
         M       	78.000000  85.0  32.0   NaN  65.000000
All              	61.333333  64.5  48.2  60.5  58.789474
# 以class_id与gender做分组汇总数据,聚合统计score列,针对age的每个值列级分组统计,添加行、列小计
print(data.pivot_table(index=['class_id', 'gender'], values=['score'], columns=['age'], margins=True, aggfunc='max'))
#ps:
	                	score                      
age  class_id gender  	20    21    22    23 All
                            
1        F       		52.0  38.0  67.0   NaN  67
         M       		98.0  74.0  26.0   NaN  98
2        F       		68.0  46.0  87.0   NaN  87
         M        		NaN  65.0  29.0  89.0  89
3        F       		34.0  79.0   NaN  32.0  79
         M       		78.0  85.0  32.0   NaN  85
All              		98.0  85.0  87.0  89.0  98

交叉表

交叉表(cross-tabulation, 简称crosstab)是一种用于计算分组频率的特殊透视表

# 按照class_id分组,针对不同的gender,统计数量
print(pd.crosstab(data.class_id, data.gender, margins=True))

pandas可视化

基本绘图:绘图

import pandas as pd
import numpy as np
import matplotlib.pyplot as mp 

df = pd.DataFrame(np.random.randn(10,4),index=pd.date_range('2018/12/18',periods=10), columns=list('ABCD'))
df.plot()
mp.show()

plot方法允许除默认线图之外的少数绘图样式。 这些方法可以作为plot()kind关键字参数。这些包括 :

  • barbarh为条形
  • hist为直方图
  • scatter为散点图

条形图

#条形图
df = pd.DataFrame(np.random.rand(10,4),columns=['a','b','c','d'])
df.plot.bar()
# df.plot.bar(stacked=True)
mp.show()

直方图

#直方图
df = pd.DataFrame()
df['a'] = pd.Series(np.random.normal(0, 1, 1000)-1)
df['b'] = pd.Series(np.random.normal(0, 1, 1000))
df['c'] = pd.Series(np.random.normal(0, 1, 1000)+1)
print(df)
df.plot.hist(bins=20)
mp.show()

散点图

#散点图
df = pd.DataFrame(np.random.rand(50, 4), columns=['a', 'b', 'c', 'd'])
df.plot.scatter(x='a', y='b')
mp.show()

饼状图

df = pd.DataFrame(3 * np.random.rand(4), index=['a', 'b', 'c', 'd'], columns=['x'])
df.plot.pie(subplots=True)
mp.show()
数据读取与存储

读取与存储csv:

# filepath 文件路径。该字符串可以是一个URL。有效的URL方案包括http,ftp和file 
# sep 分隔符。read_csv默认为“,”,read_table默认为制表符“[Tab]”。
# header 接收int或sequence。表示将某行数据作为列名。默认为infer,表示自动识别。
# names 接收array。表示列名。
# index_col 表示索引列的位置,取值为sequence则代表多重索引。 
# dtype 代表写入的数据类型(列名为key,数据格式为values)。
# engine 接收c或者python。代表数据解析引擎。默认为c。
# nrows 接收int。表示读取前n行。

pd.read_table(
    filepath_or_buffer, sep='\t', header='infer', names=None,index_col=None, dtype=None, engine=None, nrows=None) 
pd.read_csv(
    filepath_or_buffer, sep=',', header='infer', names=None, 
    index_col=None, dtype=None, engine=None, nrows=None)
DataFrame.to_csv(excel_writer=None, sheetname=None, header=True, index=True, index_label=None, mode=’w’, encoding=None) 

读取与存储excel:

# io 表示文件路径。
# sheetname 代表excel表内数据的分表位置。默认为0。 
# header 接收int或sequence。表示将某行数据作为列名。默认为infer,表示自动识别。
# names 表示索引列的位置,取值为sequence则代表多重索引。
# index_col 表示索引列的位置,取值为sequence则代表多重索引。
# dtype 接收dict。数据类型。
pandas.read_excel(io, sheetname=0, header=0, index_col=None, names=None, dtype=None)
DataFrame.to_excel(excel_writer=None, sheetname=None, header=True, index=True, index_label=None, mode=’w’, encoding=None) 

读取与存储JSON:

# 通过json模块转换为字典,再转换为DataFrame
pd.read_json('../ratings.json')

movielens电影评分数据分析

需求如下:

  1. 读取数据,从用户表读取用户信息、同样方法,导入电影评分表、电影数据表。
  2. 合并数据表
  3. 对数据初步描述分析
  4. 查看每一部电影不同性别的平均评分并计算分歧差值,之后排序
  5. 算出每部电影平均得分并对其进行排序
  6. 查看评分次数多的电影并进行排序
  7. 过滤掉评分条目数不足250条的电影
  8. 评分最高的十部电影
  9. 查看不同年龄的分布情况并且采用直方图进行可视化
  10. 在原数据中标记出用户位于的年龄分组
  11. 可视化显示movies_ratings中不同类型电影的频数

jupyter notebook实现

#%% md   
# movielens电影评分数据分析(上)
#%%
import numpy as np
import pandas as pd
#%% md
## 读取数据
#%%
# 从用户表读取用户信息
users = pd.read_table('users.dat', header=None, names=['UserID','Gender','Age','Occupation','Zip-code'], sep='::',engine='python')
#%%
# 打印列表长度,共有6040条记录
print(len(users))   
#%%
# 查看前五条记录
users.head(5)
#%%
# 同样方法,导入电影评分表
ratings = pd.read_table('ratings.dat', header=None, names=['UserID', 'MovieID', 'Rating', 'Timestamp'], sep='::',engine='python')
# 打印列表长度
print(len(ratings))
print(ratings.head(5))
# 同样方法,导入电影数据表
movies = pd.read_table('movies.dat', header=None, names=['MovieID', 'Title', 'Genres'], sep='::',engine='python')
print(len(movies))
print(movies.head(5))
#%% md
## 合并数据表
#%%
# 导入完成之后,我们可以发现这三张表类似于数据库中的表
# 要进行数据分析,我们就要将多张表进行合并才有助于分析 先将users与ratings两张表合并再跟movied合并
data = pd.merge(pd.merge(users, ratings), movies)
data.tail(5)
#%% md
## 对数据初步描述分析
#%%
data.describe()
#%%
data.info()
#%% md
## 查看数据
#%%
# 合并后的每一条记录反映了每个人的年龄,职业,性别,邮编,电影ID,评分,时间戳,电影信息,电影分类等一系列信息
# 比如我们查看用户id为1的所有信息
data[data.UserID==1]
#%% md
## 查看每一部电影不同性别的平均评分并计算分歧差值,之后排序
#%%
# 查看每一部电影不同性别的平均评分 data_gender接收
data_gender=data.pivot_table(index='Title',columns='Gender',values='Rating',aggfunc='mean')
data_gender.head()
#%%
# 查看电影分歧最大的那部电影,在原数据中体现
data_gender['diff']=np.fabs(data_gender.F-data_gender.M)
data_gender.head()
#%%
# 男女电影分歧最大进行排序 data_gender_sorted接收
data_gender_sorted=data_gender.sort_values(by='diff',ascending=False)
data_gender_sorted.head(10)
#%% md
## 算出每部电影平均得分并对其进行排序
#%%
#算出每部电影平均得分并对其进行排序 data_mean_rating 接收
data_mean_rating=data.pivot_table(index='Title',values='Rating',aggfunc='mean')
data_mean_rating.head()

#%%
# 对电影平均得分排序
data_mean_rating_sorted=data_mean_rating.sort_values(by='Rating',ascending=False)
data_mean_rating_sorted.head()
#%% md
## 查看评分次数多的电影并进行排序 
#%%
# 查看评分次数多的电影并进行排序   data_rating_num接收
data_rating_num=data.groupby('Title').size()
data_rating_num.head(10)
#%%
#进行排序
data_rating_num_sorted=data_rating_num.sort_values(ascending=False)
data_rating_num_sorted.head()
#%% md
# movielens电影评分数据分析(下)
#%% md
## 过滤掉评分条目数不足250条的电影
#%%
#过滤掉评分条目数不足250条的电影
hot_movies=data_rating_num[data_rating_num>250]
hot_movies.head()
#%%
#对评分数量进行排序,并取前20条数据
hot_movies_sorted=hot_movies.sort_values(ascending=False)
hot_movies_sorted[:20]
#%% md
## 评分最高的十部电影

#%%
#评分最高的十部电影
movies_stats=data.groupby('Title').agg({'Rating':[np.size,np.mean]})
movies_stats.head(10)
# 被评论的次数>=100
atleast_100=movies_stats['Rating']['size']>=100
movies_stats[atleast_100].sort_values([('Rating','mean')],ascending=False)[:10]
#%% md
## 查看不同年龄的分布情况并且采用直方图进行可视化
#%%
import matplotlib.pyplot as plt
users.Age.plot.hist(bins=30)
plt.title('users_ages')
plt.xlabel('age')
plt.ylabel('count of age')
plt.show()
#%% md
## 在原数据中标记出用户位于的年龄分组
#%%
labels=['0-9','10-19','20-29','30-39','40-49','50-59','60-69','70-79']
data['age_group']=pd.cut(data.Age,range(0,81,10),labels=labels)
data.head()
data['age_group'].value_counts().plot(kind='bar')
plt.xticks(rotation=45)
plt.show()
#%% md
## 电影评分表中计算不同类型电影的频数
#%%
#对数据进行规整-movies
movie_clean_1=pd.DataFrame(movies.Genres.str.split('|').tolist(),index=movies.MovieID)
movie_clean_1.head()
movie_clean_2=movie_clean_1.stack().reset_index()
movie_clean_2.head()
#%%
#删除level_1列,将columns为0的列重命名为genres,并重新定义数据框为movies_genres
movies_genres=movie_clean_2.drop('level_1',axis=1).rename(columns={0:'Genres'})
movies_genres.head()
#%%
#将原movies数据中的genres列替换成movies_genres,得到规整化处理后的movies数据 
movies=pd.merge(movies.drop('Genres',axis=1),movies_genres)
movies.head(10)
#%%
#合并。构建电影评分数据集movie_ratings
movie_ratings=ratings.merge(movies.drop('Title',axis=1),how='inner',on='MovieID')
movie_ratings.head()
#%%
#计算movies_ratings中不同类型电影的频数
movies_ratings_sorted=movie_ratings.groupby(['Genres'])['MovieID'].size()
movies_ratings_sorted.sort_values(ascending=False).plot(kind='bar')
# movies_ratings_sorted.
plt.xticks(rotation=45)
plt.show()
#%%

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值