数据分析-3 pandas

numpy能够帮我们处理处理数值型数据,但是这还不够
很多时候,我们的数据除了数值之外,还有字符串,还有时间序列等。比如:单细胞测序的结果中除了数值之外还有样本信息、基因信息等。所以,numpy能够帮助我们处理数值,但是pandas除了处理数值之外(基于numpy),还能够帮助我们处理其他类型的数据。
pandas is an open source, BSD-licensed library providing high-performance, easy-to-use data structures and data analysis tools for the Python programming language.

pandas的常用数据类型:
1.Series 一维,带标签数组
2.DataFrame 二维,Series容器

1. Series和外部数据读取

Series对象本质上由两个数组构成。一个数组构成对象的键(index,索引),一个数组构成对象的值(values),键-->值。

  • 创建Series(可以通过传入列表或字典来创建。当传入字典时,字典的键就是生成的Series的索引)
import pandas as pd
t1=pd.Series([1,2,31,12,3,4])
print(t1) #得到带标签的索引
# 0     1
# 1     2
# 2    31
# 3    12
# 4     3
# 5     4
# dtype: int64
print(type(t1))
# <class 'pandas.core.series.Series'>
t2=pd.Series([1,2,3,5],index=list('abcd')) #手动设定索引
print(t2)
# a    1
# b    2
# c    3
# d    5
# dtype: int64

#通过字典来创建  其中的索引就是字典的键
temp_dict={'name':'ahui','age':24,'tel':1001}
t3=pd.Series(temp_dict)
print(t3)
# name    ahui
# age       24
# tel     1001
# dtype: object

Series的dtype修改方式和numpy相同

对于一个陌生的series类型,我们如何知道他的索引和具体的值呢?

temp_dict={'name':'ahui','age':24,'tel':1001}
t3=pd.Series(temp_dict)
print(t3.index)
#Index(['name', 'age', 'tel'], dtype='object')
print(t3.values)
# ['ahui' 24 1001]
for i in t3.index:
    print(i)
# name
# age
# tel
  • Series的切片和索引
    切片:直接传入start end或者步长即可
    索引:一个的时候直接传入序号或者index,多个的时候传入序号或者index的列表
import pandas as pd
temp_dict={'name':'ahui','age':24,'tel':1001}
t3=pd.Series(temp_dict)
print(t3)
# name    ahui
# age       24
# tel     1001
# dtype: object
print(t3['age']) #通过索引来取
#24
print(t3[0])#通过位置(下标)来取
#ahui
print(t3[:2])  #取连续的值
# name    ahui
# age       24
# dtype: object
print(t3[[0,2]]) #取不连续的值
# name    ahui
# tel     1001
# dtype: object

#布尔索引
import pandas as pd
t1=pd.Series([1,2,31,12,3,4])
# print(t1[t1>10])
# 2    31
# 3    12
# dtype: int64

ndarray的很多方法都可以运用于series类型,比如argmax、clip等。
注意:series的where方法与ndarray不同(其他几乎都一样)

  • 读取外部数据
import pandas as pd
#pandas读取 csv
df=pd.read_csv('../dogNames2.csv')
print(df)

2. dataframe

  • 创建dataframe
import pandas as pd
import numpy as np
t1=pd.DataFrame(np.arange(12).reshape(3,4))
print(t1)
#    0  1   2   3   #列索引 
# 0  0  1   2   3
# 1  4  5   6   7
# 2  8  9  10  11

#通过字典创建
d2={'name':['xm','xh'],'age':[10,11],'tel':[1011,1001]}
t2=pd.DataFrame(d2)
print(t2)
#   name  age   tel
# 0   xm   10  1011
# 1   xh   11  1001

d3=[{'name':'xm','age':10,'tel':1011},{'name':'ej','age':8},{'name':'xm','tel':1051}]
t3=pd.DataFrame(d3)
print(t3)
#   name   age     tel
# 0   xm  10.0  1011.0
# 1   ej   8.0     NaN
# 2   xm   NaN  1051.0

DataFrame对象既有行索引,又有列索引
行索引,表明不同行,横向索引,叫index,0轴,axis=0
列索引,表名不同列,纵向索引,叫columns,1轴,axis=1

#创建的时候设定索引
t4=pd.DataFrame(np.arange(12).reshape(3,4),index=list('abc'),columns=list('lmno'))
print(t4)
#    l  m   n   o
# a  0  1   2   3
# b  4  5   6   7
# c  8  9  10  11
  • DataFrame的基本属性和方法
import pandas as pd
d3=[{'name':'xm','age':10,'tel':1011},{'name':'ej','age':8},{'name':'xm','tel':1051}]
t3=pd.DataFrame(d3)
print(t3)
#   name   age     tel
# 0   xm  10.0  1011.0
# 1   ej   8.0     NaN
# 2   xm   NaN  1051.0
print(t3.index)
#RangeIndex(start=0, stop=3, step=1)
print(t3.columns)
# Index(['name', 'age', 'tel'], dtype='object')
print(t3.shape)
#(3, 3)
print(t3.dtypes)
# name     object
# age     float64
# tel     float64
# dtype: object
print(t3.ndim) #查看有几个维度
#2

print(t3.head(1))
#   name   age     tel
# 0   xm  10.0  1011.0
print(t3.tail(1))
#   name  age     tel
# 2   xm  NaN  1051.0
print(t3.info()) #展示t3的概览
# <class 'pandas.core.frame.DataFrame'>
# RangeIndex: 3 entries, 0 to 2
# Data columns (total 3 columns):
#  #   Column  Non-Null Count  Dtype
# ---  ------  --------------  -----
#  0   name    3 non-null      object
#  1   age     2 non-null      float64
#  2   tel     2 non-null      float64
# dtypes: float64(2), object(1)
# memory usage: 200.0+ bytes
# None
print(t3.describe()) #快速统计dataframe中数值属性的列
#              age          tel
# count   2.000000     2.000000
# mean    9.000000  1031.000000
# std     1.414214    28.284271
# min     8.000000  1011.000000
# 25%     8.500000  1021.000000
# 50%     9.000000  1031.000000
# 75%     9.500000  1041.000000
# max    10.000000  1051.000000

按照某一列来进行排序:df.sort_values(by="某一列",ascending=False)

  • 索引
    1)通过方括号来取
    方括号里写数字,表示取行,对行进行操作
    方括号里写字符串,表示取列索引,对列进行操作
import pandas as pd
df=pd.read_csv('../dogNames2.csv')
#取行或取列
print(df[:20])
print(df['Row_Labels'])

2)pandas之loc
df.loc通过标签索引行数据

import pandas as pd
import numpy as np
t3=pd.DataFrame(np.arange(12).reshape(3,4),index=list('abc'),columns=list('WXYZ'))
print(t3)
print(t3.loc['a','Z'])
#3
print(type(t3.loc['a','Z']))
#<class 'numpy.int64'>
print(t3.loc['a']) #取整行
# W    0
# X    1
# Y    2
# Z    3
# Name: a, dtype: int64
print(t3.loc[['a','c'],:]) #取多行多列
#    W  X   Y   Z
# a  0  1   2   3
# c  8  9  10  11
print(t3.loc[['a'],'W':'Y']) #❗️冒号在loc里是闭合的,即会选择到冒号后面的数据
#    W  X  Y
# a  0  1  2

3)pandas之iloc
df.iloc通过位置获取行数据

import pandas as pd
import numpy as np
t3=pd.DataFrame(np.arange(12).reshape(3,4),index=list('abc'),columns=list('WXYZ'))
print(t3)
#    W  X   Y   Z
# a  0  1   2   3
# b  4  5   6   7
# c  8  9  10  11
print(t3.iloc[1,:])
# W    4
# X    5
# Y    6
# Z    7
# Name: b, dtype: int64
print(t3.iloc[:,2])
# a     2
# b     6
# c    10
# Name: Y, dtype: int64
print(t3.iloc[:,[2,1]])
#     Y  X
# a   2  1
# b   6  5
# c  10  9
print(t3.iloc[[0,2],[2,1]])
#     Y  X
# a   2  1
# c  10  9
print(t3.iloc[1:,:2])
#    W  X
# b  4  5
# c  8  9
t3.iloc[1:,:2]=30  #赋值
print(t3)
#     W   X   Y   Z
# a   0   1   2   3
# b  30  30   6   7
# c  30  30  10  11
t3.iloc[1:,:2]=np.nan #不需要转化成浮点型 
print(t3)
#      W    X   Y   Z
# a  0.0  1.0   2   3
# b  NaN  NaN   6   7
# c  NaN  NaN  10  11

4)pandas之布尔索引
&:且
|:或

import pandas as pd
import numpy as np
t4=pd.DataFrame(np.arange(24).reshape(4,6),index=list('abcd'),columns=list('UVWXYZ'))
print(t4)
#     U   V   W   X   Y   Z
# a   0   1   2   3   4   5
# b   6   7   8   9  10  11
# c  12  13  14  15  16  17
# d  18  19  20  21  22  23
print(t4[(t4['W']>5)&(t4['Y']>10)])
#     U   V   W   X   Y   Z
# c  12  13  14  15  16  17
# d  18  19  20  21  22  23
print(t4[(t4['W']>5)|(t4['Y']>10)])
#     U   V   W   X   Y   Z
# b   6   7   8   9  10  11
# c  12  13  14  15  16  17
# d  18  19  20  21  22  23
  • 缺失值的处理

判断数据是否为NaN:pd.isnull(df),pd.notnull(df)

处理方式1:删除NaN所在的行列dropna (axis=0, how='any', inplace=False)
处理方式2:填充数据,t.fillna(t.mean()),t.fiallna(t.median()),t.fillna(0)

处理为0的数据:t[t==0]=np.nan #只有0代表数据缺失时需要这样做
当然并不是每次为0的数据都需要处理
计算平均值等情况,nan是不参与计算的,但是0会

import pandas as pd
import numpy as np
t3=pd.DataFrame(np.arange(12).reshape(3,4),index=list('abc'),columns=list('WXYZ'))
t3.iloc[1:,:2]=np.nan
print(t3)
#      W    X   Y   Z
# a  0.0  1.0   2   3
# b  NaN  NaN   6   7
# c  NaN  NaN  10  11
print(pd.isnull(t3))
#        W      X      Y      Z
# a  False  False  False  False
# b   True   True  False  False
# c   True   True  False  False
print(pd.notnull(t3))
#        W      X     Y     Z
# a   True   True  True  True
# b  False  False  True  True
# c  False  False  True  True
print(t3[pd.notnull(t3['W'])]) #选取W这一行不为nan的行
#      W    X  Y  Z
# a  0.0  1.0  2  3

#处理方式1:dropna删除
print(t3.dropna(axis=0)) #axis=0表示删除行
#      W    X  Y  Z
# a  0.0  1.0  2  3
print(t3.dropna(axis=1)) #删除列
#     Y   Z
# a   2   3
# b   6   7
# c  10  11
print(t3.dropna(axis=0,how='all')) #一行全部是na值才删除,否则不删。这个参数默认是any,只要有na值就会删除
#      W    X   Y   Z
# a  0.0  1.0   2   3
# b  NaN  NaN   6   7
# c  NaN  NaN  10  11
#print(t3.dropna(axis=0,how='any',inplace=True)) #inplace默认是False,设置为True时会对dataframe进行原地修改

#处理方式2:fillna替换
print(t3.fillna(0)) #用0替换
#      W    X   Y   Z
# a  0.0  1.0   2   3
# b  0.0  0.0   6   7
# c  0.0  0.0  10  11
print(t3.fillna(t3.mean()))  #也可以用inplace设置是否原地修改 
#      W    X   Y   Z
# a  0.0  1.0   2   3
# b  0.0  1.0   6   7
# c  0.0  1.0  10  11

⚠️pandas之字符串方法

练习:现在假设我们有一个组关于狗的名字的统计数据。(数据来源:https://www.kaggle.com/new-york-city/nyc-dog-names/data
问题1:查看使用次数最高的前几个名字df.sort_values(by="Count_AnimalName",ascending=False)
问题2:假如我们想找到所有的使用次数超过70的狗的名字/超过70且不超过90的狗的名字/超过70且名字字符串长度大于4的狗的名字,应该怎么选择?

#问题1
import pandas as pd
df=pd.read_csv('../dogNames2.csv')
#dataframe中排序的方法
df=df.sort_values(by="Count_AnimalName",ascending=False)
print(df.head(10))
#问题2
#大于70的
print(df[df["Count_AnimalName"]>70])
#大于70 小于90的 ⚠️要使用&而不是and,否则会报错 
print(df[(df["Count_AnimalName"]>70)&(df["Count_AnimalName"]<90)]) 
#大于70且名字字符串长度大于4的
print(df[(df["Row_Labels"].str.len()>4)&(df["Count_AnimalName"]>70)])

3. 统计方法和字符串离散化

  • 统计方法
统计方法 描述
count 非NA值的数量
describe 针对Series或DF的列计算汇总统计
min,max 最小值和最大值
argmin,argmax 最小值和最大值的索引位置(整数)
idxmin,idxmax 最小值和最大值的索引值
quantile 样本分位数(0到1)
sum 求和
mean 均值
median 中位数
mad 根据均值计算平均绝对离差
var 方差
std 标准差
skew 样本值的偏度(三阶矩)
kurt 样本值的峰度(四阶矩)
cumsum 样本值的累计和
cummin,cummax 样本值的累计最大值和累计最小值
cumprod 样本值的累计积
diff 计算一阶差分(对时间序列很有用)
pct_change 计算百分数变化

练习:假设现在我们有一组从2006年到2016年1000部最流行的电影数据,我们想知道这些电影数据中评分的平均分,导演的人数,演员的人数等信息,我们应该怎么获取?对于这一组电影数据,如果我们想获取rating,runtime的分布情况,应该如何呈现数据?
数据来源:https://www.kaggle.com/damianpanek/sunday-eda/data

import pandas as pd
import numpy as np
file_path="../IMDB-Movie-Data的副本.csv"
df=pd.read_csv(file_path)
#查看矩阵基本信息
#print(df.info())

#获取电影数据中评分的均值
print(df['Rating'].mean())
#6.723199999999999

#获取导演的人数
print(len(set(df['Director'])))
print(len(df['Director'].unique()))
#644

#获取所有演员的人数  演员是用逗号隔开的
temp_actors_list=df['Actors'].str.split(',').tolist() #tolist()生成的是大列表,里面每个小列表内才是多个演员的名字
actors_list=np.array(temp_actors_list).flatten() #二维变一维
#actors_list=[i for j in temp_actors_list for i in j] #和上一行代码等价
actors_num=len(set(actors_list))
print(actors_num)
#996

# 获取rating,runtime的分布情况
# 选择图形,直方图
#准备数据
runtime_data=df["Runtime (Minutes)"].values
#画图也可以直接用Series,这里用Values应该是为了方便切片。直接用series切片要用iloc,不然直接切片会根据index值进行。比如排序后想更改第一个值,不用values也不用iloc会改变index的值而不是排序后的第一个
max_runtime=runtime_data.max()
min_runtime=runtime_data.min()
num_bin=(max_runtime-min_runtime)//5
plt.figure(figsize=(20,8),dpi=80)
plt.hist(runtime_data,num_bin)
plt.xticks(range(min_runtime,max_runtime+5,5))
plt.show()
#画rating时只需把上述代码runtime_data后面换成‘Rating’,再 调整一下步长即可。
  • 字符串离散化
    思考:对于这一组电影数据,如果我们希望统计电影分类(genre)的情况,应该如何处理数据?
    ⚠️思路:重新构造一个全为0的数组,列名为分类,如果某一条数据中分类出现过,就让0变为1
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
file_path="../IMDB-Movie-Data的副本.csv"
df=pd.read_csv(file_path)
#查看矩阵基本信息
# print(df.info())

#统计分类的列表
temp_list=df['Genre'].str.split(',').tolist() #列表嵌套列表的大列表,❗️在Series里,用tolist和todict。在dataframe用to_list和to_dict
genre_list=list(set([i for j in temp_list for i in j])) #用flattern也可以
#构建全为0的数组
zeros_df=pd.DataFrame(np.zeros((df.shape[0],len(genre_list))),columns=genre_list)
# print(zeros_df)
#给每个电影出现的位置赋值为1
for i in range(df.shape[0]):
    zeros_df.loc[i, temp_list[i]]=1
#统计每个分类的电影数量和
genre_count=zeros_df.sum(axis=0)
#排序
genre_count=genre_count.sort_values()
print(genre_count)

#绘图
plt.figure(figsize=(20,8),dpi=80)
_x=genre_count.index
_y=genre_count.values
plt.bar(range(len(_x)),_y)
plt.xticks(range(len(_x)),_x)
plt.show()

4. 数据的合并和分组聚合

  • 数据的合并
    1)join:默认情况下是把索引相同的数据合并到一起
import pandas as pd
import numpy as np
df1=pd.DataFrame(np.ones((2,4)),index=['A','B'],columns=list('abcd'))
print(df1)
#      a    b    c    d
# A  1.0  1.0  1.0  1.0
# B  1.0  1.0  1.0  1.0
df2=pd.DataFrame(np.ones((3,3)),index=['A','B','C'],columns=list('xyz'))
print(df2)
#      x    y    z
# A  1.0  1.0  1.0
# B  1.0  1.0  1.0
# C  1.0  1.0  1.0
print(df1.join(df2))
#      a    b    c    d    x    y    z
# A  1.0  1.0  1.0  1.0  1.0  1.0  1.0
# B  1.0  1.0  1.0  1.0  1.0  1.0  1.0
print(df2.join(df1))
#      x    y    z    a    b    c    d
# A  1.0  1.0  1.0  1.0  1.0  1.0  1.0
# B  1.0  1.0  1.0  1.0  1.0  1.0  1.0
# C  1.0  1.0  1.0  NaN  NaN  NaN  NaN

2)merge:按照指定的把数据按照一定的方式合并到一起

import pandas as pd
import numpy as np
df1=pd.DataFrame(np.ones((2,4)),index=['A','B'],columns=list('abcd'))
print(df1)
#      a    b    c    d
# A  1.0  1.0  1.0  1.0
# B  1.0  1.0  1.0  1.0
df2=pd.DataFrame(np.arange(9).reshape((3,3)),columns=list('fax'))
print(df2)
#      f    a    x
# 0    0    1    2
# 1    3    4    5
# 2    6    7    8

#默认取交集 参数how='inner
df3=df1.merge(df2) 
print(df3)
#      a    b    c    d  f  x
# 0  1.0  1.0  1.0  1.0  0  2
# 1  1.0  1.0  1.0  1.0  0  2
df3=df1.merge(df2,on='a')   #on等于按照什么进行合并
print(df3)
#     a    b    c    d  f  x
#0  1.0  1.0  1.0  1.0  0  2
#1  1.0  1.0  1.0  1.0  0  2
df1.loc['A','a']=100
df3=df1.merge(df2,on='a')
# print(df3)
#      a    b    c    d  f  x
# 0  1.0  1.0  1.0  1.0  0  2

#外连接
df4=df1.merge(df2,on='a',how='outer') #一个有另一个没有的用NAN补齐
print(df4)
#        a    b    c    d    f    x
# 0  100.0  1.0  1.0  1.0  NaN  NaN
# 1    1.0  1.0  1.0  1.0  0  2
# 2    4.0  NaN  NaN  NaN  3  5
# 3    7.0  NaN  NaN  NaN  6  8

#左连接
df5=df1.merge(df2,on='a',how='left') #以左边的df为准,也就是df1
print(df5)
#        a    b    c    d    f    x
# 0  100.0  1.0  1.0  1.0  NaN  NaN
# 1    1.0  1.0  1.0  1.0  0.0  2.0

#右连接
df6=df1.merge(df2,on='a',how='right') #以右边的df为准,也就是df2
print(df6)
#      a    b    c    d  f  x
# 0  1.0  1.0  1.0  1.0  0  2
# 1  4.0  NaN  NaN  NaN  3  5
# 2  7.0  NaN  NaN  NaN  6  8
  • 分组和聚合
    分组:
    grouped = df.groupby(by="columns_name")
    grouped是一个DataFrameGroupBy对象,是可迭代的
    grouped中的每一个元素是一个元组
    元组里面是(索引(分组的值),分组之后的DataFrame)
    聚合:

思考:现在我们有一组关于全球星巴克店铺的统计数据,如果我想知道美国的星巴克数量和中国的哪个多,或者我想知道中国每个省份星巴克的数量的情况,应该怎么做?如果我们需要对国家和省份进行分组统计,应该怎么操作?(数据来源:https://www.kaggle.com/starbucks/store-locations/data

import pandas as pd
import numpy as np
file_path="../starbucks_store_worldwide的副本.csv"
df=pd.read_csv(file_path)
# print(df.head(1))
# print(df.info())
grouped=df.groupby(by='Country')
print(grouped)
#<pandas.core.groupby.generic.DataFrameGroupBy object at 0x7f80932d5dc0>
#DataFrameGroupby是一个元祖,元组第一个值按照xx进行分组的那个值。比如按国家分组,第一个值就是国家。第二个值为第一个值所对应的列表。DataFrameGroupby可以进行遍历,可以调用聚合方法

#调用聚合方法
print(grouped.count()) #对datafame里的所有列都进行了count
country_count=grouped["Brand"].count() #除了brand,别的也可以,只要没有缺失值
print(country_count['US'])
# 13608
print(country_count['CN'])
# 2734

#统计中国每个省份星巴克的数量
china_data=df[df['Country']=='CN']
grouped=china_data.groupby(by='State/Province').count()['Brand']
print(grouped)


#对国家和省份进行分组统计
#数据按照多个条件进行分组,返回Series。(by=后面不仅可以跟字符串,还可以跟列表)
grouped=df['Brand'].groupby(by=[df['Country'],df['State/Province']]).count()
print(grouped) #得到带有两个索引的Series(因为是按照两个条件来分组的)
#数据按照多个条件进行分组,返回DataFrame
grouped1=df[['Brand']].groupby(by=[df['Country'],df['State/Province']]).count()
grouped2=df.groupby(by=[df['Country'],df['State/Province']])[['Brand']].count()
grouped3=df.groupby(by=[df['Country'],df['State/Province']]).count()[['Brand']]
print(grouped1,type(grouped1))

⚠️一个[]取series,两个[[]]取dataframe

import pandas as pd
import numpy as np
df1=pd.DataFrame(np.ones((2,4)),index=['A','B'],columns=list('abcd'))
print(df1)
#      a    b    c    d
# A  1.0  1.0  1.0  1.0
# B  1.0  1.0  1.0  1.0
print(df1['c'])
print(type(df1['c']))
# A    1.0
# B    1.0
# Name: c, dtype: float64
# <class 'pandas.core.series.Series'>
print(df1[['c']])
print(type(df1[['c']]))
#      c
# A  1.0
# B  1.0
# <class 'pandas.core.frame.DataFrame'>
print(df1[['b','c']])
print(type(df1[['b','c']]))
#      b    c
# A  1.0  1.0
# B  1.0  1.0
# <class 'pandas.core.frame.DataFrame'>
  • 索引

简单的索引操作:
获取index:df.index
指定index :df.index = ['x','y']
重新设置index : df.reindex(list("abcedf"))
指定某一列作为index :>df.set_index("Country",drop=False)
返回index的唯一值:>df.set_index("Country").index.unique()

import pandas as pd
import numpy as np
df1=pd.DataFrame(np.ones((2,4)),index=['A','B'],columns=list('abcd'))
df1.loc['A','a']=100
print(df1)
#        a    b    c    d
# A  100.0  1.0  1.0  1.0
# B    1.0  1.0  1.0  1.0
print(df1.index)
#Index(['A', 'B'], dtype='object')

#索引赋值
df1.index=['a','b']
print(df1)
#        a    b    c    d
# a  100.0  1.0  1.0  1.0
# b    1.0  1.0  1.0  1.0
print(df1.index)
# Index(['a', 'b'], dtype='object')
print(df1.reindex(['a','f']))
#        a    b    c    d
# a  100.0  1.0  1.0  1.0
# f    NaN  NaN  NaN  NaN

#把某一列设置为索引
print(df1.set_index('a'))
#          b    c    d
# a
# 100.0  1.0  1.0  1.0
# 1.0    1.0  1.0  1.0
print(df1.set_index('b',drop=False)) #索引可以是一致的 
#          a    b    c    d
# b
# 1.0  100.0  1.0  1.0  1.0
# 1.0    1.0  1.0  1.0  1.0

#返回唯一值
print(df1['d'].unique())
#[1.]

复合索引:
print(df1.set_index(['b','a']))
#              c    d
# b   a
# 1.0 100.0  1.0  1.0
#     1.0    1.0  1.0
print(df1.set_index(['a','b']).index)
# MultiIndex([(100.0, 1.0),
#             (  1.0, 1.0)],
#            names=['a', 'b'])

a = pd.DataFrame({'a': range(7),'b': range(7, 0, -1),'c': ['one','one','one','two','two','two', 'two'],'d': list("hjklmno")})
print(a)
#    a  b    c  d
# 0  0  7  one  h
# 1  1  6  one  j
# 2  2  5  one  k
# 3  3  4  two  l
# 4  4  3  two  m
# 5  5  2  two  n
# 6  6  1  two  o
b=a.set_index(['c','d'])
print(b)
#        a  b
# c   d      
# one h  0  7
#     j  1  6
#     k  2  5
# two l  3  4
#     m  4  3
#     n  5  2
#     o  6  1

c=b['a']
print(c) #得到有两个索引的series
# c    d
# one  h    0
#      j    1
#      k    2
# two  l    3
#      m    4
#      n    5
#      o    6
# Name: a, dtype: int64
d=c.swaplevel()
print(d)
# d  c
# h  one    0
# j  one    1
# k  one    2
# l  two    3
# m  two    4
# n  two    5
# o  two    6
# Name: a, dtype: int64
print(c['one']['j'])
# 1
print(b.loc['one'].loc['h'])
# a    0
# b    7
# Name: h, dtype: int64
#dataframe和series的区别在于索引的时候如果按标签来取需要加上loc,否则方括号内的内容会被认为是列

练习1:
使用matplotlib呈现出店铺总数排名前10的国家
使用matplotlib呈现出每个中国每个城市的店铺数量

import pandas as pd
import numpy as np
from matplotlib import font_manager
from matplotlib import pyplot as plt
my_font=font_manager.FontProperties(fname="/System/Library/Fonts/PingFang.ttc") #更改字体
file_path="../starbucks_store_worldwide的副本.csv"
df=pd.read_csv(file_path)
print(df.info())
# 使用matplotlib呈现出店铺总数排名前10的国家
#准备数据
data1=df.groupby(by='Country').count()['Brand'].sort_values(ascending=False)[:10]
print(data1)
_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()

#使用matplotlib呈现出每个中国每个城市的店铺数量 画了top25
df=pd.read_csv(file_path)
df=df[df['Country']=='CN']
data1=df.groupby(by='City').count()['Brand'].sort_values(ascending=False)[:25]
_x=data1.index
_y=data1.values
# 绘图
plt.figure(figsize=(20,12),dpi=80)
plt.barh(range(len(_x)),_y,height=0.3,color='orange')
plt.yticks(range(len(_x)),_x,fontproperties=my_font)
plt.show()

练习2:
现在我们有全球排名靠前的10000本书的数据,那么请统计一下下面几个问题:1. 不同年份书的数量;2. 不同年份书的平均评分情况;
(数据来源:https://www.kaggle.com/zygmunt/goodbooks-10k

import pandas as pd
import numpy as np
from matplotlib import font_manager
from matplotlib import pyplot as plt
file_path="../books的副本.csv"
df=pd.read_csv(file_path)
print(df.info())
print(df['original_publication_year'])
#删除年份中缺失值的行
data1=df[pd.notnull(df['original_publication_year'])]
#不同年份书的数量
grouped=data1.groupby(by='original_publication_year').count()['title']
print(grouped)
#不同年份书的平均评分情况
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(range(len(_x))[::10],_x[::10].astype(int),rotation=45)
plt.show()

5. 时间序列

问题. 现在我们有2015到2017年25万条911的紧急电话的数据,请统计出出这些数据中不同类型的紧急情况的次数,如果我们还想统计出不同月份不同类型紧急电话的次数的变化情况,应该怎么做呢?(数据来源:https://www.kaggle.com/mchirico/montcoalert/data

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,961评论 5 473
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,444评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,009评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,082评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,101评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,271评论 1 278
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,738评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,395评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,539评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,434评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,481评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,160评论 3 317
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,749评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,816评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,038评论 1 256
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,548评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,140评论 2 341

推荐阅读更多精彩内容