Task01:Pandas基础(1天)
Pandas基础
文件的读取与写入
查看pandas版本
导入库文件,并查看Pandas版本。
import pandas as pd
import numpy as np
print(pd.__version__)
‘1.0.3’
读取
(1)csv 格式
df = pd.read_csv('data/table.csv')
(2)txt 格式
df_txt = pd.read_table('data/table.txt')
(3)xls或xlsx格式(需要安装xlrd包)
df_excel = pd.read_excel('data/table.xlsx')
写入
(1)csv 格式
#df.to_csv('data/new_table.csv')
df.to_csv('data/new_table.csv', index=False) #保存时除去行索引
(2)xls或xlsx格式(需要安装openpyxl包)
df.to_excel('data/new_table2.xlsx', sheet_name='Sheet1', index=False)
基本数据结构
pandas包含两种数据类型:Series和DataFrame。
series是一种一维数据结构,每一个元素都带有一个索引,与一维数组的含义相似,其中索引可以为数字或字符串。series结构名称:
dataframe是一种二维数据结构,数据以表格形式(与excel类似)存储,有对应的行和列。dataframe结构名称:
1. Series
创建一个Series
对于一个Series,其中最常用的属性为值(values),索引(index),名字(name),类型(dtype)
我尝试分别从列表,数组,字典构建series:
mylist = list('abcde') # 列表
myarr = np.arange(5) # 数组
mydict = dict(zip(mylist, myarr)) # 字典
# 构建方法
ser1 = pd.Series(mylist)
ser2 = pd.Series(myarr)
ser3 = pd.Series(mydict, name='这是一个Series')
访问Series属性
取出某一个元素
使series的索引列转化为dataframe的列
ser = pd.Series(mydict)
# series转换为dataframe
df = ser.to_frame()
# 索引列转换为dataframe的列
df.reset_index(inplace=True)
Series的特点
我们指导numpy的多维数组(ndarray),当然,它也包括一维数组,Series类似一维数组,为啥还要介绍Series呢?或Series有哪些特点?Series一个最大特点就是可以使用标签索引,序列及ndarray也有索引,但都是位置索引或整数索引,这种索引有很多局限性,如根据某个有意义标签找对应值?切片时采用类似[2:3]的方法,只能取索引为2这个元素等等,无法精确定位。
Series的标签索引(它位置索引自然保留)使用起来就方便多了,而且定位也更精确,不会产生歧义。
2. DataFrame
创建一个DataFrame
生成DataFrame有很多,比较常用的有导入等长列表、字典、numpy数组、数据文件等。
data = {
'name': ['zhanghua', 'liuting', 'gaofei', 'hedong'],
'age': [40, 45, 50, 46],
'addr': ['jiangxi', 'pudong', 'beijing', 'xian']
}
d2 = pd.DataFrame(data)
d2
重新构造索引
# 重新构造索引
d3 = pd.DataFrame(data,
columns=['name', 'age', 'addr'],
index=['a', 'b', 'c', 'd'])
d3
获取数据
修改数据
我们可以像操作数据库表一样操作DataFrame,删除数据,插入数据、修改字段名、索引名、修改数据等,以下通过一些实例来说明。
d3.drop('d', axis=0) ###删除行,如果欲删除列,使axis=1即可
###从副本中删除,原数据没有被删除
###添加一行,注意需要ignore_index=True,否则会报错
d3.append({'name': 'wangkuan', 'age': 38, 'addr': 'henan'}, ignore_index=True)
###添加一行,并创建一个新DataFrame
d4 = d3.append({
'name': 'wangkuan',
'age': 38,
'addr': 'henan'
},
ignore_index=True)
d4
d4.index=['a','b','c','d','e'] ###修改d4的索引
d4
# del 删除列
del d4['addr']
d4
#pop方法直接在原来的DataFrame上操作,且返回被删除的列,与python中的pop函数类似
d4['col1']=[1,2,3,4,5]
d4.pop('col1')
调用属性和方法
索引对齐特性
df1 = pd.DataFrame({'A':[1,2,3]},index=[1,2,3])
df2 = pd.DataFrame({'A':[1,2,3]},index=[3,1,2])
df1-df2 #由于索引对齐,因此结果不是0
可以看到这里df1和df2的索引是没有对齐的。
df1.assign(C=pd.Series(list('def'))) # 由于索引不一致,导致这里出现NaN
DataFrame的特点
DataFrame除了索引有位置索引也有标签索引,而且其数据组织方式与MySQL的表极为相似,除了形式相似,很多操作也类似,这就给我们操作DataFrame带来极大方便。这些是DataFrame特色的一小部分,它还有比数据库表更强大的功能,如强大统计、可视化等等。
DataFrame几要素:index、columns、values等,columns就像数据库表的列表,index是索引,当然values就是值了。
# 稍微改一下就行,在list首字符前加一个空格看看效果
df1.assign(C=pd.Series(list(' def')))
# 成功,Nice!
常用基本函数
df = pd.read_csv('data/table.csv')
df['Physics'].nunique() # nunique显示有多少个唯一值
df['Physics'].unique() # unique显示所有的唯一值
df['Physics'].count() # count返回非缺失值元素个数
df['Physics'].value_counts() # value_counts返回每个元素有多少个
d1 = pd.DataFrame(np.arange(12).reshape((3, 4)),
index=['a', 'b', 'c'],
columns=['a1', 'a2', 'a3', 'a4'])
d1
d1.apply(lambda x:x.max()-x.min(),axis=0) ###列级处理
d1.applymap(lambda x:x*2) ###处理每个元素
排序
练习
【练习一】
现有一份关于美剧《权力的游戏》剧本的数据集,请解决以下问题:(a)在所有的数据中,一共出现了多少人物?
(b)以单元格计数(即简单把一个单元格视作一句),谁说了最多的话?
(c)以单词计数,谁说了最多的单词?
import pandas as pd
df = pd.read_csv('data/Game_of_Thrones_Script.csv')
df.head()
# (a)在所有的数据中,一共出现了多少人物?
df['Name'].nunique()
# (b)以单元格计数(即简单把一个单元格视作一句),谁说了最多的话?
df['Name'].value_counts()
df['Name'].value_counts().index[0]
# (c)以单词计数,谁说了最多的单词?
"""
我的思路:(不用groupby)
1.先把每个sentence的单词统计出来;
2.进行匹配;
3.把每个名字的单词数求和;
4.最后排序;
"""
# 新增一列,统计单词数
df['Words'] = df['Sentence'].apply(lambda x: len(x.strip().split()))
# 提取所有不重复人名
people = df['Name'].unique()
# 把‘Name’列和‘Words’列进行合并
group = list(zip(df['Name'], df['Words']))
numbers = [] # 存放每个角色的单词数总和
## 外循环:遍历所有不重复人名
# 内循环:遍历所有样本
for i in range(len(people)):
number = [] # 存放每个角色每句话所说单词数
for word in group:
# 如果名字匹配,把‘Words’列元素传入number
if word[0] == people[i]:
number.append(word[1])
# 遍历完一遍每一个人名,对其所说单词数求和
numbers.append(sum(number))
# 找到最大值索引
index = numbers.index(max(numbers))
# 找到最大值索引对应人名,即我们的结果
max_people = people[index]
max_people
【练习二】
现有一份关于科比的投篮数据集,请解决如下问题:
(a)哪种action_type和combined_shot_type的组合是最多的?
(b)在所有被记录的game_id中,遭遇到最多的opponent是一个支?
df2 = pd.read_csv('data/Kobe_data.csv',index_col='shot_id')
df2.head()
#index_col的作用是将某一列作为行索引
# (a)哪种action_type和combined_shot_type的组合是最多的?
group = pd.Series(list(zip(df2['action_type'], df2['combined_shot_type'])))
group.value_counts().index[0]
第二问,我开始的思路和参考答案有偏差,误以为每个opponent只对应一个game_ID,导致结果错误。
# (b)在所有被记录的game_id中,遭遇到最多的opponent是一个支?
uniq = df2['game_id'].unique()
group = list(zip(df2['game_id'], df2['opponent']))
opponent_max = {}
for i in range(len(uniq)):
opponent = []
for g in group:
if g[0] == uniq[i]:
opponent.append(g[1])
opponent_max[opponent[0]] = len(opponent)
# 结果
z = list(opponent_max.keys())[list(opponent_max.values()).index(
max(opponent_max.values()))]
z
这是参考答案给的思路。
pd.Series(
list(
list(
zip(*(pd.Series(list(zip(df['game_id'], df['opponent']))).unique()
).tolist()))[1])).value_counts().index[0]
参考内容
- 教程仓库连接
- 《利用Python进行数据分析》