一、pandas数据合并
1、join:默认情况下把行索引相同的数据合并在一起
join方法是基于index连接dataframe,merge方法是基于column连接,连接方法有内连接,外连接,左连接和右连接,与merge一致。
join操作按照左边原则进行,左边有几行,结果就会有几行,列为join操作双方列的总和,在左边未出现的赋值为NaN
import pandas as pd
import numpy as np
def myPd():
t1 = pd.DataFrame(np.arange(12).reshape(3, 4), index=list("abc"), columns=list("ABCD"))
print(t1)
t2 = pd.DataFrame(np.ones((2, 5)), columns=list("VWXYZ"), index=list("ab"))
print(t2)
print(t1.join(t2))
if __name__ == '__main__':
myPd()
2、merge:按照指定的列把数据按照一定的方式合并到一起
pandas的merge方法是基于共同列,将两个dataframe连接起来。merge方法的主要参数:
- left/right:左/右位置的dataframe。
- how:数据合并的方式。left:基于左dataframe列的数据合并;right:基于右dataframe列的数据合并;outer:基于列的数据外合并(取并集);inner:基于列的数据内合并(取交集);默认为'inner'。
- on:用来合并的列名,这个参数需要保证两个dataframe有相同的列名。
- left_on/right_on:左/右dataframe合并的列名,也可为索引,数组和列表。
- left_index/right_index:是否以index作为数据合并的列名,True表示是。
- sort:根据dataframe合并的keys排序,默认是。
- suffixes:若有相同列且该列没有作为合并的列,可通过suffixes设置该列的后缀名,一般为元组和列表类型。
merges通过设置how参数选择两个dataframe的连接方式,有内连接,外连接,左连接,右连接,下面通过例子介绍连接的含义。
二、pandas分组聚合
df.groupby(by = "属性名“) | 分组 | 按照by指定的属性进行分组 |
grouped.count() | 聚合 | grouped是分组好的数据,count是按照分组进行计数 |
现在我们有一组关于全球星巴克店铺的统计数据,如果我们想知道US的星巴克数量和中国的哪个多,或者我们想知道中国每个省份星巴克的数量的情况,那么应该怎么办?
1、Starbucks数据描述信息
2、数据分组(按国家)
import pandas as pd
import numpy as np
file_path = "E:/python/pyData/starbucks.csv"
df = pd.read_csv(file_path)
#分组
grouped = df.groupby(by="Country")
print(grouped)
#pandas.core.groupby.generic.DataFrameGroupBy
#可以进行遍历
for i,j in grouped:
print(i)
print("*" * 100)
print(j)
print("-" * 100)
美国(US)对应门店详细信息:
3、数据聚合(按国家-Country)
#数据聚合
country_count = grouped["Brand"].count()
print(country_count)
print("CN_number:", country_count["US"])
print("US_number:", country_count["CN"])
4、统计中国所有省份的星巴克数目
思路:先在全球分布文件中选中中国,最后在对中国的数据按照省分组
- 注意:此处关于中国的省份用数字代号表示
china_data = df[df["Country"] == "CN"]
china_grouped = china_data.groupby(by="State/Province").count()["Brand"]
print(china_grouped)
部分数据展示:
5、数据按照多个条件进行分组
(1)如果我们需要对国家和省份进行分组统计,具体操作:
grouped = df.groupby(by=[df["Country"], df["State/Province"]])
(2)获取分组之后的某一部分数据
grouped = df.groupby(by=["Country", "State/Province"])["Country"].count()
(3)对某几列数据进行分组
grouped = df["Country"].groupby(by=[df["Country"], df["State/Province"]]).count()
- 注:输出中,grouped是一个Series类型
以上返回是Series类型,若想让返回值是DataFrame类型做法:
法1:grouped = df[["Brand"]].groupby(by=[df["Country"], df["State/Province"]]).count()
法2:grouped2 = df.groupby(by=[df["Country"], df["State/Province"]])[["Brand"]].count()
法3:grouped3 = df.groupby(by=[df["Country"], df["State/Province"]]).count()[["Brand"]]
三、索引和复合索引
1、简单的索引操作
- 获取index:df.index
- 指定index:df.index = ["x", “y”]
- 重新设置index:df.reindex(list("abcd"))
- 指定某一列作为索引(index):df.set_index("COUNTRY", drop = false)
- 返回index的唯一值,df.set_index("COUNTRY").index_unique()
注:drop参数的作用:在设定某列为索引时,是否删除对应的列
reindex重新指定索引与index直接指定新索引的区别:
- reindex指定新索引,其实是在原索引中取出对应存在的行作为新的行,原索引中未出现的,对应列的数据均赋值为NaN
import pandas as pd
import numpy as np
def myPd():
df = pd.DataFrame(np.arange(12).reshape(3, 4), index=list("ABC"), columns=list("abcd"))
print(df)
print(df.index)
df.index = ["x", "y", "z"]
print(df)
print(df.index)
df = df.reindex(list("wxy"))
print(df)
print(df.index)
#设置符合索引
df = df.set_index(["a", "b"], drop=False)
print(df)
if __name__ == '__main__':
myPd()
2、重排分级排序
有时需要重新调整某条轴上各级别的顺序,或根据指定级别上的值对数据进行排序。swaplevel接受两个级别编号或名称,并返回一个互换了级别的新对象(但数据不会发生变化):
import pandas as pd
import numpy as np
def myPd():
df = pd.DataFrame(np.arange(12).reshape(3, 4), index=list("ABC"), columns=list("abcd"))
df = df.set_index(["a", "b"], drop=False)
print(df)
df = df.swaplevel()
print(df)
if __name__ == '__main__':
myPd()
四、分组聚合练习
1、使用matplotlib呈现出店铺综述排名前十的国家
2、使用matplotlib呈现出中国每个城市的店铺数量
1、需求1
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
def myDeal():
file_path = "E:/python/pyData/starbucks.csv"
df = pd.read_csv(file_path)
#数据准备,降序并取出前十
data1 = df.groupby(by="Country").count()["Brand"].sort_values(ascending=False)[:10]
_x = data1.index
_y = data1.values
#画图
plt.figure(figsize=(20, 8), dpi=80)
plt.bar(range(len(_x)), _y)
plt.xticks(range(len(_x)), _x)
plt.show()
if __name__ == '__main__':
myDeal()
2、需求2
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from matplotlib import font_manager
def myDeal():
my_font = font_manager.FontProperties(fname="C:/Windows/Fonts/HGSS1_CNKI.TTF")
file_path = "E:/python/pyData/starbucks.csv"
df = pd.read_csv(file_path)
df = df[df["Country"] == "CN"]
#数据准备
data1 = df.groupby(by="City").count()["Brand"].sort_values(ascending=False)[:15]
_x = data1.index
_y = data1.values
#画图
plt.figure(figsize=(20, 8), dpi=80)
plt.bar(range(len(_x)), _y, width=0.3, color="orange")
plt.xticks(range(len(_x)), _x, fontproperties=my_font)
plt.show()
if __name__ == '__main__':
myDeal()
五、书籍统计练习
现在我们有全球排名靠前的10000本书的数据,那么请统计一下下面几个问题:
- 不同年份书籍的数量
- 不同年份书的平均评分情况
1、数据文件描述信息
2、不同年份书的平均评分情况
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
def myPd():
file_path = "E:/python/pyData/books.csv"
df = pd.read_csv(file_path)
# print(df.info())
#处理original_publication_year列的缺失值,删除,取出不为NaN的值
data1 = df[pd.notna(df["original_publication_year"])]
#求不同年份的平均值(折线图)
grouped = data1["average_rating"].groupby(by=data1["original_publication_year"]).mean()
print(grouped)
#绘图
_x = grouped.index
_y = grouped.values
plt.figure(figsize=(20, 8), dpi=80)
plt.plot(range(len(_x)), _y)
plt.xticks(list(range(len(_x)))[::10], _x, rotation=45)
plt.show()
if __name__ == '__main__':
myPd()
六、紧急救援电话案例
现在我们有2015到2017年的25万条911的紧急电话的数据,请统计出这些数据中不同类型的紧急情况的次数
数据来源:https://www.kaggle.com/mchirico/montcoalert/data
import pandas as pd
import numpy as np
def myPD():
file_path = "E:/python/pyData/911.csv"
df = pd.read_csv(file_path)
print(df.head(1))
print(df.info())
#获取分类
temp_list = df["title"].str.split(": ").tolist()
cate_list = list(set([i[0] for i in temp_list]))
#构造全为0的数组
zeros_df = pd.DataFrame(np.zeros((df.shape[0], len(cate_list))), columns=cate_list)
#赋值,按列赋值处理速度快
for cate in cate_list:
zeros_df[cate][df["title"].str.contains(cate)] = 1
sum_ret = zeros_df.sum(axis=0)
print(sum_ret)
if __name__ == '__main__':
myPD()