python数据分析-pandas自学笔记

  • Post author:
  • Post category:python



pandas常用数据类型

Series:一维,

带标签

的数组

DataFrame:二维,Series容器

1.创建Series

#使用列表生成一个Series
import pandas as pd
s = pd.Series([1, 2, 3, 4])
print(s)
'''
0    1
1    2
2    3
3    4
dtype: int64
'''
# 使用数组生成一个Series
import pandas as pd
import numpy as np
s  = pd.Series(np.arange(6))
print(s)
'''
0    0
1    1
2    2
3    3
4    4
5    5
dtype: int64
'''
# 使用列表生成序列,并且指定索引
import pandas as pd

s1 = pd.Series([1, 2, 3, 4], index=['A', 'B', 'C', 'D'])

s2 = pd.Series([1,2,3,4,5], index=list('ABCDE'))    #调用list方法将字符串转换成列表类型

print(s1)
print(s2)
'''
A    1
B    2
C    3
D    4
dtype: int64
A    1
B    2
C    3
D    4
E    5
dtype: int64
'''
# 使用一个字典生成Series,其中字典的键,就是索引
import pandas as pd
s = pd.Series({'name':'张三', 'age':20, 'tel':10086})
print(s)
'''
name       张三
age        20
tel     10086
dtype: object
'''

2.Series的切片和索引

import pandas as pd
s2 = pd.Series([1,2,3,4,5], index=list('ABCDE'))
print( s2['B'] )    #通过索引查找
print( s2[2] )      #通过位置查找
print( s2[s2>2] )       #通过条件查找
print( s2[:2] )     #连续位置查找
print( s2[ [1,3] ] )        #不连续位置查找
print( s2[ ['B','D'] ] )        #通过多个索引查找
'''
2
3
C    3
D    4
E    5
dtype: int64
A    1
B    2
dtype: int64
B    2
D    4
dtype: int64
B    2
D    4
dtype: int64
'''

当通过一个不存在的索引查找数据,会返回NaN

numpy中的空值:nan           pandas中的空值:NaN

import pandas as pd
s = pd.Series({'name':'张三', 'age':20, 'tel':10086})
print(s.index)      #查看Series的索引
print(s.values)     #查看Series的值
print( len(s.values) )      #查看Series的长度
'''
Index(['name', 'age', 'tel'], dtype='object')
['张三' 20 10086]
3
'''

2.pandas读取外部数据

#读取xxx文件,如果不指定路径就寻找当前目录

pandas.read_xxx(文件名)

3.DataFrame的创建

DataFrame对象既有行索引,又有列索引

行索引:标记不同行,叫index,axis=0

列索引:标记不同列,叫columns,axis=1

pandas.DataFrame( numpy.arange(个数).reshape(行数,列数), index=, columns=)

import numpy as np
import pandas as pd
d = pd.DataFrame( np.arange(12).reshape(3,4), index=list('ABC'), columns=list('DEFG'))
print(d)
'''
   D  E   F   G
A  0  1   2   3
B  4  5   6   7
C  8  9  10  11
'''
#将字典转化成DataFrame

import numpy as np
import pandas as pd

d1 = { 'name':['xiaoming','xiaohua'],
       'age':[20,21],
       'tel':[10086,10010] }
print( pd.DataFrame(d1) )
print('-------------------------------------')

d2 = [ {'name':'xiaohong','age':32, 'tel':10010},
       {'name':'xiangming','tel':10000},
       {'name':'xiaohua','age':22} ]
print( pd.DataFrame(d2) )

'''
       name  age    tel
0  xiaoming   20  10086
1   xiaohua   21  10010
-------------------------------------
        name   age      tel
0   xiaohong  32.0  10010.0
1  xiangming   NaN  10000.0
2    xiaohua  22.0      NaN
'''

4.DataFrame中的查询

DataFrame的基础属性查询

代码 功能 对象名.shape 行数、列数 对象名.dtype 列数据类型 对象名.ndim 数据维度 对象名.index 获取行索引 对象名.columns 获取列索引 对象名.values 返回对象值,二维ndarray数组

DataFrame的整体情况查询
代码 功能
对象名.head(行数) 显示头部几行,默认5行
对象名.tail(行数) 显示末尾几行,默认5行
对象名.info() 相关信息概览
对象名.describe() 快速综合统计结果:计数、均值、标准差、最大值…

#DataFrame中排序的方法

对象名=pandas.read_csv(文件名)        #先给对象赋值

对象名=对象名.sort_values(by=字段,ascending=False)            #默认升序,False是降序

#DataFrame取数据:[ ]内写数字筛选行,写字符串筛选列

对象名[起始行:结束行]         #取行数据

对象名[字段名]        #取列数据

对象名[起始行:结束行] [字段名]        #取限定行列

#DataFrame之loc查找(注意

:

在loc里是闭合的)

对象名.loc[行标签,列标签]

对象名.iloc[行位置,列位置]

import numpy as np
import pandas as pd
d = pd.DataFrame( np.arange(12).reshape(3,4), index=list('ABC'), columns=list('DEFG'))

print( d.loc[ : , ['E','F'] ] )
'''
   E   F
A  1   2
B  5   6
C  9  10
'''

5.pandas字符串处理方法

函数名称 函数功能和描述
lower() 将字符串转换为小写。
upper() 将字符串转换为大写。
len() 得出字符串的长度。
strip() 去除字符串两边的空格(包含换行符)。
split() 用指定的分割符分割字符串。
cat(sep=””) 用给定的分隔符连接字符串元素。
get_dummies() 返回一个带有独热编码值的 DataFrame 结构。
contains(pattern) 如果子字符串包含在元素中,则为每个元素返回一个布尔值 True,否则为 False。
replace(a,b) 将值 a 替换为值 b。
count(pattern) 返回每个字符串元素出现的次数。
startswith(pattern) 如果 Series 中的元素以指定的字符串开头,则返回 True。
endswith(pattern) 如果 Series 中的元素以指定的字符串结尾,则返回 True。
findall(pattern) 以列表的形式返出现的字符串。
swapcase() 交换大小写。
islower() 返回布尔值,检查 Series 中组成每个字符串的所有字符是否都为小写。
issupper() 返回布尔值,检查 Series 中组成每个字符串的所有字符是否都为大写。
isnumeric() 返回布尔值,检查 Series 中组成每个字符串的所有字符是否都为数字。
repeat(value) 以指定的次数重复每个元素。
find(pattern) 返回字符串第一次出现的索引位置。

6.pandas的布尔索引与NaN的处理


简单条件判断

import numpy as np
import pandas as pd
d = pd.DataFrame( np.arange(12).reshape(3,4), index=list('abc'), columns=list('DEFG'))

print( d['E']>2 )
print('---------------------------------------------------')
print( d[ d['E']>2 ] )      #返回E列中大于2的值所在的行
print('---------------------------------------------------')
print( d[ (d['E']>2) & (d['E']>6) ] )     #多条件筛选

'''
a    False
b     True
c     True
Name: E, dtype: bool
---------------------------------------------------
   D  E   F   G
b  4  5   6   7
c  8  9  10  11
---------------------------------------------------
   D  E   F   G
c  8  9  10  11
'''

&:且              |:或


NaN的处理

#判断DataFrame里的每个值是否为NaN,返回bool值

pandas.isnull(变量名)

pandas.notnull(变量名)


此例逻辑:1. pd.notnull( t3[“W”] )即在t3的W列中判断每个值是否为NaN,返回bool值;即W列a行是True,W列bc行是False。2. 在t3整个DataFrame中,返回为True的行,即一整个a行

#有NaN的行都删掉

对象名.dropna(axis=0)

对象名.dropna(axis=0, how=’any’)

#全部数据都为NaN的行才删掉

对象名.dropna(axis=0, how=’all’, inplace=False)        #inplace对原dataframe的NaN修改

#将所有NaN值填上数据


对象名.fillna(数值)

import numpy as np
import pandas as pd
d1 = [ {'name':'xiaohong','age':32, 'tel':10010},
       {'name':'xiangming','tel':10000},
       {'name':'xiaohua','age':22} ]
d2 = pd.DataFrame(d1)

print( d2.fillna( d2.mean() ) )    #填充每列的平均数

d2['age'] = d2['age'].fillna(d2['age'].mean())    #只填充其中一列
print(d2) 

'''
        name   age      tel
0   xiaohong  32.0  10010.0
1  xiangming  27.0  10000.0
2    xiaohua  22.0  10005.0
        name   age      tel
0   xiaohong  32.0  10010.0
1  xiangming  27.0  10000.0
2    xiaohua  22.0      NaN
'''

进行均值计算这些不会将NaN包括进去

因此有时候需要将某些没有意义的0转化成NaN

#将0转化成NaN
t[t==0]=np.nan

7.str方法

#筛选出含有特定字符串的行(返回bool值)


DataFrame名[字段名].str.contains()

#字符串分割(将特定列拿出来,按特定字符分开,然后形成一个新的dataframe)


DataFrame名[字段名].str.split(按什么分隔符分开, expand=)

#(expand=True那么分隔后的字符串形成两个字段,=False则返回成同个字段中的列表)

#默认False

import pandas as pd
d={'gene':{'a':'gene1','b':'gene2','c':'gene3','d':'gene4'},
   'expression':{'a':'low:0','b':'mid:3','c':'mid:4','d':'high:9'},
   'description':{'a':'transposon element','b':'nuclear genes','c':'retrotransposon','d':'unknown'}}
df=pd.DataFrame(d)
print(df)
print('-------------------------------------------')
df1=df[df['description'].str.contains('transposon')]
print(df1)
print('-------------------------------------------')
df2=df['expression'].str.split(':',expand=True)
print(df2)
print('-------------------------------------------')
df3=df['expression'].str.split(':',expand=False)
print(df3)
'''
    gene expression         description
a  gene1      low:0  transposon element
b  gene2      mid:3       nuclear genes
c  gene3      mid:4     retrotransposon
d  gene4     high:9             unknown
-------------------------------------------
    gene expression         description
a  gene1      low:0  transposon element
c  gene3      mid:4     retrotransposon
-------------------------------------------
      0  1
a   low  0
b   mid  3
c   mid  4
d  high  9
-------------------------------------------
a     [low, 0]
b     [mid, 3]
c     [mid, 4]
d    [high, 9]
'''

df1逻辑:1. df[‘description’].str.contains(‘transposon’)筛选出含有description字段中有transposon字符串的行,返回True否则返回False。2. df[df[‘description’].str.contains(‘transposon’)]输出df中为True的行列。3. 将筛选过后的行列赋给df1

8.pandas常用统计方法


datasourse.7z – 蓝奏云

资源中的IMDB-Movie-Data.csv

import numpy as np
import pandas as pd
df = pd.read_csv(r'C:\Users\LG\Desktop\data source\100电影\IMDB-Movie-Data.csv')      #导入文件
#查看字段,字段行数,字段数据类型
print(df.info())
#获取电影平均评分
print(df['Rating'].mean())
#导演的人数
print(len(set(df['Director'].tolist())))         #set()是转化成集合以去重,tolist()是转化成列表
print(len(df['Director'].unique()))       #unique()返回去重后的一个列表
print(df['Director'].nunique())
#演员的人数
actors_list = df['Actors'].str.split(',')       #每个电影的演员表生成列表,各列表再组成一个Series
actors = [i for j in actors_list for i in j]     #一层循环遍历一部电影的演员列表,另一层循环遍历一个演员列表里的每个演员
actors_sum = len(set(actors))       #set()使列表转为集合以去重,len()计算长度
print(actors_sum)
print('--------------------------')
#电影时长的最大值
max_time = df['Runtime (Minutes)'].max()        #最大时长
max_time_index = df['Runtime (Minutes)'].argmax()       #最大时长对应的索引
#电影时长的最小值
min_time = df['Runtime (Minutes)'].min()        #最小时长
min_time_index = df['Runtime (Minutes)'].argmin()       #最小时长对应的索引
#电影时长的中值
median_time = df['Runtime (Minutes)'].median()


统计每个分类下有几部电影

思路:先将所有电影类别作为表头创建一个全为0的DataFrame,遍历每部电影,在该电影属于的类别下改值为1(一部电影可能属于多个类别)

import numpy as np
import pandas as pd
df = pd.read_csv(r'C:\Users\LG\Desktop\data source\100电影\IMDB-Movie-Data.csv')
#将分类名去重提取出形成一个列表
categories_list = df['Genre'].str.split(',').tolist()       #.tolist()方法将Series转化为一个大列表内套着多个小列表
categories = list( set( i for j in categories_list for i in j))
print(categories)
#构造全为0的数组
zeros_df = pd.DataFrame(np.zeros((df.shape[0],len(categories))),columns=categories)
#给每个电影出现分类的位置赋值为1
for i in range(df.shape[0]):
    #zeros_df.loc[0, ['Sci-fi', 'Musical']] = 1,避免了双重循环
    zeros_df.loc[i,categories_list[i]] = 1
#统计每个分类的电影的数量和
count = zeros_df.sum(axis=0)
#排序
count = count.sort_values()
print(count)

9.数据合并

join根据行索引,merge根据列索引


join

#将行索引相同的数据合并到一起


DataFrame1.join(DataFrame2)

#(以DataFrame1的索引为主,DataFrame2多余的行去掉、少的行数据显示为NaN)


merge


DataFrame1.merge(DataFrame2, on=’字段名’,how=’连接方式’)

连接方式:

inner(默认)——交集,指定字段中相同的数据为连接,连上该行其它数据(相当于mysql的inner join)

outer——并集

right——右边为准,NaN补全

left——左边为准,NaN补全


DataFrame1.merge(DataFrame2,left_on=’1的某字段’,right_on=’2的某字段’,how=’连接方式’)

10.分组聚合


要分组的Series或DataFrame.groupby(by=’字段名’)


datasourse.7z – 蓝奏云

中的星巴克directory.csv

import pandas as pd
import numpy as np
df = pd.read_csv(r'C:\Users\LG\Desktop\data source\星巴克\directory.csv')
print(df.info())

grouped = df.groupby(by='Country')      #grouped里每一个元素是一个元组
#可迭代对象
for i,j in grouped:
    print(i)
    print('-'*100)
    print(j)
    print('*'*100)
#分组后限定筛选
print(df[df['Country']=='US'])
#调用聚合方法
grouped.count()     #同个城市的所有字段分别求和
print(grouped['Brand'].count())     #可以选定某个不缺失数据的字段,避免上面那种每个字段求和值都一样

#统计美国的星巴克数量和中国哪个多
country_count = grouped['Brand'].count()
print(country_count['US'])
print(country_count['CN'])
#中国每个省份星巴克的数量情况
china_data = df[df['Country'] == 'CN']
province = china_data.groupby(by='State/Province')['Brand'].count()
print(province)

Series外嵌套一个[ ]就能使其返回成DataFrame

#数据按照多个条件进行分组,返回带有两个索引的Series
group2 = df['Brand'].groupby(by=[df['Country'],df['State/Province']]).count()
print(group2)
#数据按照多个条件进行分组,返回DataFrame
group3 = df[['Brand']].groupby(by=[df['Country'],df['State/Province']]).count()

11.索引和复合索引

#获取索引

df.index

#指定索引

df.index = [‘x’,’y’]

#重新指定索引

df.reindex( [‘a’,’b’,’c’] )        #有这些索引的行保留,没有的填充为NaN。df中其它行删掉

#指定某一列作为索引

df.set_index(‘字段名’, drop=False)        #False意味着不把表头删掉,留下一个索引为表头名的空行

#返回index的唯一值(索引是可以重复的)

df.set_index(‘字段名’).index.unique()

#通过双索引查找数据

#DataFrame之loc查找(注意

:

在loc里是闭合的)

对象名.loc[ [行标签1,行标签2], 列标签]

双索引下,不能直接按内索引查找

#转换内外索引后再查找

对象名.swaplevel().loc[ [行标签2] ]

12.时间序列


datasourse.7z – 蓝奏云

中的911.csv

#生成一段时间范围

pandas.date_range(start= , end= , periods= , freq=频率 )

频率

#把时间字符串转化为时间序列


df[‘时间字段名’]=pandas.to_datetime(df[‘时间字段名’],format= )

#对于python无法格式化的可以通过format告诉python它的格式

13.重采样

重采样指将时间序列从从一个频率转化为另一个频率进行处理的过程。将高频率数据转化为低频率数据为降采样,低频率转化为高频率数据为升采样。

#时间频率转化

DataFrame名.resample(‘频率’).聚合方法

#聚合方法:.mean()、.count()等等

import numpy as np
import pandas as pd
df = pd.read_csv(r"C:\Users\LG\Desktop\data source\911\911.csv")
#统计不同月份电话次数的情况
df['timeStamp'] = pd.to_datetime(df['timeStamp'])
df.set_index('timeStamp',inplace=True)      #inplace=True意味着原地替换
count = df['title'].resample('M').count()
print(count)



版权声明:本文为m0_46224483原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。