pandas详细基本操作及电影数据分析实例

Pandas:Pandas是Python中分析结构化数据的工具集合
基础是Numpy:高性能矩阵运算
图形库matplotlib: 提供数据可视化功能

Pandas基本操作:
创建一行或一列数据,Series:

s = pd.Series([1, 3, 5, np.NaN, 8]) 

创建日期序列:

dates = pd.date_range('20200510', periods = 6) # 日期序列,periods表示几个日期

创建二维数组:

data = pd.DataFrame(np.random.randn(6, 4), index=datas, columns=list('ABCD')) # 6行4列数组,行索引是日期,列索引是ABCD 

使用字典方法创建二维数组:

 d = {'A': 1, 'B': datas, 'C': range(6), 'D': np.arange(6)}  
 df = pd.DataFrame(d)  

查看数据:

 data.head(2) # 查看前2行数据,默认为前5行  
 data.tail(2) # 查看后2行数据,默认为后5行
 data.index # 查看行标签
 data.columns # 查看列标签
 data.values # 查看值
 data.discribe() # 查看整体情况,分别为:有效数据个数,平均值,方差,最小值,四分位,二分位,四分之三分位,最大值

转置:

data.T

数据排序:

data.sort_index(axis=0) # 对行标签排序,升序 
data.sort_index(axis=0, ascending=False) # 对行标签排序,降序
data.sort_index(axis=1) # 对列标签排序,升序 
data.sort_index(axis=1, ascending=False) # 对列标签排序,降序
data.sort_values(by='A') # 通过A列的值进行排序

数据选择:

data.A # A列数据
data['A'] # A列数据
data[2:4] # 2-4行数据
data['2020-05-12':'2020-05-13'] # 按行标签选择数据
# 推荐.loc()(按标签)/.iloc()(按位置标签)选择数据,效率高
data.loc['2020-05-12':'2020-05-13'] # 按标签选择数据
data.iloc[2:4] # 按位置标签选择数据
data.loc['2020-05-12':'2020-05-13', ['B', 'C']] # 指定区间选择数据
data.at[pd.Timestamp('20200510'), 'B'] # 特定位置的值,必须传入数据的原生数据结构, 更高效
data.iloc[1:3, 2:4] # 1-3行,2-4列数据
data.iloc[:, 2:4]  # 所有行, 2-4列数据
data.iloc[1, 1] # 第一行第一列数据
data.iat[1, 1] # 第一行第一列数据, 更高效
data[data > 0] # 选取所有值中大于0的数据
data[data.A > 0] # 选取A列值中大于0的数据
# copydata,创建data2,给data2添加一列TAG
data2 = data.copy()
tag = ['a', 'a', 'b', 'b', 'c', 'c']
data2['TAG'] = tag 
data2[data2.TAG.isin(['a','c'])] #  isin选择

数据修改,数据选择方式都可用于数据修改,注意序列长度需要匹配,例:

data.iat[1, 1] = 100 # 指定位置数据修改
data.A = range(6) # 修改A列数据,注意序列长度要匹配

处理丢失数据:

dates = pd.date_range('20200510', periods = 6) # 日期序列,periods表示几个日期
data = pd.DataFrame(np.random.randn(6, 4), index=datas, columns=list('ABCD')) # 6行4列数组,行索引是日期,列索引是ABCD
df = data.reindex(index=dates[0:4], columns=list(data.columns)+['E']) # 通过对data重新索引,创建新二维数组df,并添加新一列‘E’, 默认‘E’列无数据
df.loc[dates[1:3], 'E'] = 2 # 向‘E’列指定位置添加数据,形成具有数据丢失的新二维数组df
df.dropna() # 丢掉含有空数据的行, 在copy的基础上操作的,原数据df并没有被改变
df.fillna(value=8) # 用设定值填充空数据, 在copy的基础上操作的,原数据df并没有被改变
pd.isnull(df).any # 判断一个数据集里是否包含空数据
pd.isnull(df).any() # 哪列有空数据
pd.isnull(df).any().any() # 对于有空数据的列直接判断空数据

求平均值:

df.mean() # 默认按列求平均值,空数据不参与计算
df.mean(axis=1) # 按行求平均值,空数据不参与计算

求累加值:

df.cumsum() # 空数据不参与计算
df.apply(np.cumsum) # 同上

广播的概念,二维数组减一维序列,相当于把一维序列扩展,二维数组每一列都减去这个序列:

s = pd.Series([1, 3, 5, np.nan, 6, 8], index=dates)# 创建一个六个元素的序列
data.sub(s, axis='index') # 二维数组减去一维序列, 行标签作为关键字索引(列相减),若参与计算的序列中含有空数据,那么该行/列计算结果为空数据(空数据不参与运算)

数值的处理:

s = pd.Series(np.random.randint(10, 20, size=20)) # 产生20个10-20之间的随机数
s.value_counts() # 每个数据出现多少次
s.mode() # 出现次数最多的数据是哪个

数据合并:

df1 = pd.concat([df.iloc[:1], df.iloc[1:3], df.iloc[3:]])
df == df1
# 另一个数据合并方法
# 创建两个数据集
left = pd.DataFrame({'key':['foo', 'foo'], 'leftval':[1, 2]})
right = pd.DataFrame({'key':['foo', 'foo'], 'rightval':[3, 4]})
pd.merge(left, right, on='key') # 传入数据集,通过‘key’来合并

插入数据:

data.append(s, ignore_index=True)

分类统计:

df2 = pd.DataFrame({'A': ['foo', 'bar', 'foo', 'bar', 'foo', 'bar','foo', 'bar'], 'B': ['one', 'two', 'three', 'one', 'two', 'three', 'three', 'two'], 'C': np.random.randn(8), 'D': np.random.randn(8)}) # 创建数据集
df2.groupby('A').sum() # 通过A列分组,所有‘foo’分为一组,所有‘bar’分为一组,返回每组的累加值情况
df2.groupby(['A', 'B']).sum() # 多个分组
df2.groupby(['B', 'A']).sum() # 多个分组'A','B'列顺序先后,会影响分组结果

数据整形:数据集行和列索引互换

tuples = list(zip(*[['bar', 'bar', 'baz', 'baz',
                     'foo', 'foo', 'qux', 'qux'],
                    ['one', 'two', 'one', 'two',
                     'one', 'two', 'one', 'two']])) # 创建一个元组列表,作为数据集的行索引
index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second']) # 创建索引
df =pd.DataFrame(np.random.randn(8, 2), index=index, columns=['A', 'B']) # 创建数组(二维行索引,一维列索引)
stacked = df.stack() # 把列('A','B')索引转换成行索引,此时行索引变成3层
stacked.index # 查看索引
stacked.unstack() # 转换回去,恢复原状
stacked.unstack().unstack() # 再转换一次将会把外层(第二层)行索引转换为列索引

数据透视:看指定部分数据

df = pd.DataFrame({'A':['one', 'one', 'two', 'three'] * 3,
                   'B':['A', 'B', 'C'] * 4,
                   'C':['foo', 'foo', 'foo', 'bar', 'bar', 'bar'] * 2,
                   'D':np.random.randn(12),
                   'E':np.random.randn(12)}) # 创建数组
df.pivot_table(values=['D'], index=['A', 'B'], columns=['C'])# 以‘A’,‘B’列为行索引, 以‘C’列为列索引,针对'D'列数值,生成新的数组
df[df.A == 'one'] # ‘A'列中为’one‘的数据
df[df.A == 'one'].groupby('C').mean() # 对‘A'列中为’one‘的数据分组,求平均值

时间序列:

rng = pd.date_range('20200511', periods=600, freq='s') # 创建600个单位为秒的时间序列(单位默认为天)
s = pd.Series(np.random.randint(0, 500, len(rng)), index=rng) # 创建以时间序列作为行索引的序列
s.resample('2Min', how='sum') # 数据重新采样,每两分钟求和采样 (适用于python2,python3中how()函数以移除)

rng = pd.period_range('2018Q1', '2020Q1', freq='Q') # 创建以季度为单位的时间序列
rng.to_timestamp() # 转换为时间日期的格式
pd.Timestamp('20200511') - pd.Timestamp('20200429') # 时间运算,减法,等于12天
pd.Timestamp('20200501') + pd.Timedelta(days=10) # 时间运算,加法,等于2020-05-11

类别数据:

df = pd.DataFrame({'id':[1, 2, 3, 4, 5, 6], 'raw_grade':['a', 'b', 'b', 'a', 'a', 'd']}) # 创建数组
df['grade'] = df.raw_grade.astype('category') # 增加一列名为‘grade’的category类型数据
df.grade.cat.categories # category是一个特殊类型的数据,返回值为:Index(['a', 'b', 'd'], dtype='object'),相当于索引
df.grade.cat.categories = ['very good', 'good', 'bad'] # 可以对数据重命名
df = df.sort_values(by='grade', ascending=True) # 以category类型的‘grade’排序,实际上是以‘grade’的值(‘raw_grade’列的值)进行排序的

数据可视化:

s = pd.Series(np.random.randn(1000), index=pd.date_range('20180101', periods=1000)) # 创建序列
s = s.cumsum() # 对数据进行累加操作
s.plot # 数据可视化

数据读写:从磁盘中读取数据,写入数据到磁盘

df = pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD')) # 创建数组
df.to_csv('data.csv') # 写数据,格式为csv
%more data.csv # 查看数据内容
pd.read_csv('data.csv', index_col=0) # 读数据,格式为csv。第0列作为行索引

实例:MovieLens 电影数据分析 所需数据下载

import pandas as pd

# 导入用户信息
user_names = ['user_id', 'gender', 'age', 'occupation', 'zip'] # 定义列名称
users = pd.read_table('ml-1m/users.dat', sep='::', header=None, names=user_names) # 读取数据,参数分别为:数据所在路径,分隔符,表头,列名称
print(len(users)) # 查看导入数据长度,6040
users.head(8) # 查看前8行数据

# 导入电影数据
movie_names = ['movie_id', 'title', 'genres']
movies = pd.read_table('ml-1m/movies.dat', sep='::', header=None, names=movie_names)
print(len(movies))
movies.head(8)

# 导入评分数据
rating_names = ['user_id', 'movie_id', 'rating', 'timestamp']
ratings = pd.read_table('ml-1m/ratings.dat', sep='::', header=None, names=rating_names)
print(len(ratings))
ratings.head(8)

# 数据合并,有利于数据分析
data = pd.merge(pd.merge(users, ratings), movies) # 调用两次merge()函数,将数据合并
print(len(data))
data.head(8)
data[data.user_id == 1] # 用户id为1的用户,所有的数据(电影评分记录)

# 分析男生女生对同一部电影的评分差异
ratings_by_gender = data.pivot_table('rating', index='title', columns='gender', aggfunc='mean') # 数据透视,关注值是‘rating’, 行索引是'title', 列索引是'gender',数据聚合方式是求平均值
ratings_by_gender.head(8) 
ratings_by_gender['diff'] = ratings_by_gender.F - ratings_by_gender.M #添加一列'diff'为男女生评分差 = 女生评分 - 男生评分
ratings_by_gender.head(8) 
# 对评分差进行排序,观察男女评分差较大的电影
ratings_by_gender.sort_values(by='diff', ascending=True).head(8) # 升序
ratings_by_gender.sort_values(by='diff', ascending=False).head(8) # 降序

# 分析热门电影(评分次数最多的电影)
ratings_by_title = data.groupby('title').size() # 以‘title’分组,并返回每个title出现次数,也就是每部电影评分次数
ratings_by_title.sort_values(ascending=False).head(10) # 降序排序,并查看前10部热门电影

# 分析平均评分较高的电影
ratings_by_mean = data.pivot_table(values='rating', index='title', aggfunc='mean')# 数据透视,关注值是‘评分’,行索引是电影名字,聚合函数是求平均值
ratings_by_mean.head(10)
mean_ratings.sort_values(ascending=False).head(10) # 降序排序,并查看平均评分前10的电影

# 前10大热门电影的平均评分
top_10_hot = ratings_by_title.sort_values(ascending=False).head(10)
top_10_hot.index
ratings_by_mean[top10_hot.index]

# 评分前20电影的热度(评分次数)
top20_score = mean_ratings.sort_values(by='rating', ascending=False).head(20)
top20_score.index
ratings_by_title[top20_score.index]

# 分析热度较高且评分较高的电影
hot_movies = ratings_by_title[ratings_by_title > 1000] # 评分次数大于1000次的电影视作热门电影
print(len(hot_movies))
hot_movies_rating = ratings_by_mean[hot_movies.index]
hot_movies_rating.sort_values(ascending=False).head(10) # 降序排序,查看前10部评分较高且热门的电影
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值