pandas数据合并、分组聚合及其使用

一、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方法的主要参数:

  1. left/right:左/右位置的dataframe。
  2. how:数据合并的方式。left:基于左dataframe列的数据合并;right:基于右dataframe列的数据合并;outer:基于列的数据外合并(取并集);inner:基于列的数据内合并(取交集);默认为'inner'。
  3. on:用来合并的列名,这个参数需要保证两个dataframe有相同的列名。
  4. left_on/right_on:左/右dataframe合并的列名,也可为索引,数组和列表。
  5. left_index/right_index:是否以index作为数据合并的列名,True表示是。
  6. sort:根据dataframe合并的keys排序,默认是。
  7. suffixes:若有相同列且该列没有作为合并的列,可通过suffixes设置该列的后缀名,一般为元组和列表类型。

merges通过设置how参数选择两个dataframe的连接方式,有内连接,外连接,左连接,右连接,下面通过例子介绍连接的含义。

二、pandas分组聚合

df.groupby(by = "属性名“)分组按照by指定的属性进行分组
grouped.count()聚合grouped是分组好的数据,count是按照分组进行计数

现在我们有一组关于全球星巴克店铺的统计数据,如果我们想知道US的星巴克数量和中国的哪个多,或者我们想知道中国每个省份星巴克的数量的情况,那么应该怎么办?

数据来源:https://www.kaggle.com/starbucks/store-locations/data

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本书的数据,那么请统计一下下面几个问题:

  • 不同年份书籍的数量
  • 不同年份书的平均评分情况

数据来源:https://www.kaggle.com/zygmunt/goodbooks-10k

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()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Star星屹程序设计

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值