我们如果要将两个表结构相同的数据表进行合并,可以使用pandas.concat()方法。
该方法第一个参数必须是一个元组,元组中的元素是你要合并的数据表。例如,
import pandas as pd
score = pd.read_csv("score.csv") # 读取csv文件
score_concat = pd.read_csv("score_concat.csv") # 读取csv文件
concat_result = pd.concat((score, score_concat)) # 将数据表合并
concat()方法主要是为了扩充数据量,便于分析规律。而我们接下来说的pandas.merge()方法主要是将两个表结构不同的表,通过相同的键连接在一起,也就是Mysql中的各种连接。
pandas.merge()方法的前两位参数是要连接的数据表;我们可以添加on参数选择使用指定的键进行表连接,注意on参数必须是列表的形式;how参数用于指定表连接方式,诸如,内连接、外连接、左连接和右连接,分别为inner、outer、left和right,默认为内连接。例如,
df_score_info = pd.read_csv("score_info.csv")
result_merge_inner = pd.merge(df_score, df_score_info, on=["学号"]) # 内连接
result_merge_outer = pd.merge(df_score, df_score_info, how="outer", on=["学号"]) # 外连接
result_merge_left = pd.merge(df_score, df_score_info, how="left", on=["学号"]) # 左连接
result_merge_right = pd.merge(df_score, df_score_info, how="right", on=["学号"]) # 右连接
在pandas中我们可以使用mean()、sum()、min()、max()、median()等聚合函数进行数据操作,我们可以在聚合函数中添加axis参数选定数据操作方向,axis=1表示对行数据进行操作,axis=0表示对列数据进行操作。例如,
score.mean(axis=0) # axis=1按行取,axis=0按列取
当然,我们会比较多的在对数据进行分组后使用聚合函数,
result = score.loc[:,["性别", "音乐"]].groupby("性别").mean() # 选取score表中的姓名和音乐字段并按照性别分组计算平均值
result表会呈现下面的形态。
在这个表中音乐字段的数据可以直接取出,
result["音乐"]
result.values # 结果同上
但是,我们无法直接取出性别字段的值,
result["性别"] # 系统报错
这是因为性别字段的值是result表的索引,只能通过result.index的形式取出,
result.index
我们可以使用info()方法或者describe()方法获取表的信息。例如,
score.info()
结果为,
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 6 entries, 0 to 5
Data columns (total 7 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 数学 6 non-null int64
1 语文 6 non-null int64
2 英语 6 non-null int64
3 地理 6 non-null int64
4 音乐 6 non-null int64
5 体育 6 non-null int64
6 性别 6 non-null object
dtypes: int64(6), object(1)
memory usage: 464.0+ bytes
下面是describe()方法的效果,
score.describe()
结果如下图,
如果我们想要对数据表中的某一个字段的值出现的次数进行统计,可以使用value_counts()方法。例如,
score["性别"].value_counts()
结果为,
女 3
男 3
Name: 性别, dtype: int64
首先我们读取IMDB.csv文件,
import pandas as pd
df = pd.read_csv("IMDB.csv")
第一步,我们对数据大致情况进行了解,
df.info()
执行结果如下,
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 12 columns):
Rank 1000 non-null int64
Title 1000 non-null object
Genre 1000 non-null object
Description 1000 non-null object
Director 1000 non-null object
Actors 1000 non-null object
Year 1000 non-null int64
Runtime (Minutes) 1000 non-null int64
Rating 1000 non-null float64
Votes 1000 non-null int64
Revenue (Millions) 872 non-null float64
Metascore 936 non-null float64
dtypes: float64(3), int64(4), object(5)
memory usage: 93.9+ KB
我们可以看到这个表中有1000条数据,可以知道列名。
为了更加的直观看出表结构,我们可以使用head()方法或者tail()方法,取出头部或者尾部的数据,例如,
df.head(3) # 前三条数据
df.tail(3) # 最后三条数据
第二步,我们需要对数据进行清洗。但是因为,IMDB表数据非常规正,我们可以跳过这个步骤。
第三步,指标分析。我们选取的指标需要根据业务情景自行判断。
我们先选出表中电影数量最多的前十位导演。
director_count = df['Director'].value_counts() # 统计Director名出现的次数
director_count[:10]
结果如下,
Ridley Scott 8
Paul W.S. Anderson 6
M. Night Shyamalan 6
David Yates 6
Michael Bay 6
Zack Snyder 5
Woody Allen 5
J.J. Abrams 5
Peter Berg 5
Danny Boyle 5
Name: Director, dtype: int64
我们再统计总票房最高的前10位导演。
# 先按照导演将票房进行汇总
director_sum = df.loc[:,["Director","Runtime (Minutes)"]].groupby("Director").sum()
# 再将数据按照票房降序排列,并取出票房前十的数据
director_sum.sort_values(by="Runtime (Minutes)",ascending=False)[:10]
接下来,我们统计各种风格(Genre)的电影数量。
因为,每个电影都包含不止一种风格,因此,我们需要对Genre字段进行预处理,
count_dict = {} #统计结果字典
for g_str in df['Genre']: #循环遍历每一个电影字段
#将电影风格按照逗号拆分成单个风格
g_array = g_str.split(",")
#遍历一个电影具有的所有风格
for g_name in g_array:
#判断是否统计过
if g_name in count_dict:
#如果之前出现过,对统计次数+1
count_dict[g_name] += 1
else:
#如果没有在字典中,说明没有统计过,将风格出现次数,初始化为1
count_dict[g_name] = 1
count_dict
接下来,我们统计各个年份的票房总数。
因为Year字段位int64,索引最好是字符串类型,因此,我们需要对Year字段进行类型转换,
df['Year'] = df['Year'].apply(lambda x:str(x)) # 将Year字段中的所有值转换为字符串类型
df.loc[:,['Year','Revenue (Millions)']].groupby('Year').sum()
最后,我们来统计哪部电影的票房最高。
注意,我们是要获取票房最高的电影的数据,而不是最高的票房数,因此,我们不能使用max()聚合函数实现此目的。
这里,我们需要使用idxmax()方法。
其实,我们的每一个值其实都是对应下标的一个函数,f([0, 1, 2, 3]) = numpy.array([3, 5, 1, 2])。在numpy中我们可以使用argmax()方法获取最大值所对应的下标。
df['Revenue (Millions)'].idxmax()
结果如下,
50
获取下标后,我们在通过下标获取对应数据,
df[50:51]