数据帧(Dataframe)是一个矩阵样式的数据表,包含已排序的列集合,每一列可以是不同的值类型(数值、字符串、布尔值等)
数据帧既有行索引也有列索引,它被视为一个共享相同索引的Series字典。
下面是创建数据帧的方法,以及一些基本操作:
import pandas as pd
data = {
'platform': ['qq', 'weixin', 'weibo', 'taobao'],
'year': [2000, 2010, 2005, 2004],
'percent': [0.71, 0.89, 0.63, 0.82]
}
df = pd.DataFrame(data)
print(df)
#打印
platform year percent
0 qq 2000 0.71
1 weixin 2010 0.89
2 weibo 2005 0.63
3 taobao 2004 0.82
#这个看着有点像excel表格,其实也可以这么理解
print(df.head()) #调用这个方法,只会显示前五行数据
#按照我们想要的顺序生成数据帧
data = {
'platform': ['qq', 'weixin', 'weibo', 'taobao'],
'year': [2000, 2010, 2005, 2004],
'percent': [0.71, 0.89, 0.63, 0.82]
}
columns = ['year', 'platform', 'percent']
df = pd.DataFrame(data, columns=columns) #按照给定的列顺序进行排序生成数据帧
print(df)
#打印
year platform percent
0 2000 qq 0.71
1 2010 weixin 0.89
2 2005 weibo 0.63
3 2004 taobao 0.82
#如果给定的行或列不存在,那么内部数据会使用NaN替代
data = {
'platform': ['qq', 'weixin', 'weibo', 'taobao'],
'year': [2000, 2010, 2005, 2004],
'percent': [0.71, 0.89, 0.63, 0.82]
}
columns = ['year', 'platform', 'percent', 'count']
index = ['a', 'b', 'c', 'd']
df = pd.DataFrame(data, columns=columns, index=index) #如果给的列或行不存在于数据中,那么就用NaN表示数据
print(df)
#打印
year platform percent count
a 2000 qq 0.71 NaN
b 2010 weixin 0.89 NaN
c 2005 weibo 0.63 NaN
d 2004 taobao 0.82 NaN
print(df['year']) #可以使用列名获取到数据帧中该列的所有数据,返回一个Series序列
#打印
a 2000
b 2010
c 2005
d 2004
Name: year, dtype: int64
print(df.platform) #也可以通过列名直接使用.列名访问这个序列
#打印
a qq
b weixin
c weibo
d taobao
Name: platform, dtype: object
print(df.loc['a']) #获取index为‘a’的行
#打印
year 2000
platform qq
percent 0.71
count NaN
Name: a, dtype: object
#上面的‘count’列是NaN,我们可以直接更改他们的值
df['count'] = 5000
print(df)
#打印
year platform percent count
a 2000 qq 0.71 5000
b 2010 weixin 0.89 5000
c 2005 weibo 0.63 5000
d 2004 taobao 0.82 5000
#也可以传递一个数组,将他们赋值,但是要注意,传递的数组的长度一定要和数据帧的长度保持一致,否则会报错
df['count'] = [x*1000 for x in range(1, 5)]
print(df)
#打印
year platform percent count
a 2000 qq 0.71 1000
b 2010 weixin 0.89 2000
c 2005 weibo 0.63 3000
d 2004 taobao 0.82 4000
#还可以传一个序列给数据帧,序列可以设定好index,如果没有的index,它会自动设置为NaN
ser = pd.Series([1000, 3000], index=['a', 'c'])
df['count'] = ser
print(df)
#打印
year platform percent count
a 2000 qq 0.71 1000.0
b 2010 weixin 0.89 NaN
c 2005 weibo 0.63 3000.0
d 2004 taobao 0.82 NaN
#增加数据帧的列
df['check'] = df.platform == 'weixin'
print(df)
#打印
year platform percent count check
a 2000 qq 0.71 NaN False
b 2010 weixin 0.89 NaN True
c 2005 weibo 0.63 NaN False
d 2004 taobao 0.82 NaN False
#移除数据帧的列
del df['check']
print(df)
#打印
year platform percent count
a 2000 qq 0.71 NaN
b 2010 weixin 0.89 NaN
c 2005 weibo 0.63 NaN
d 2004 taobao 0.82 NaN
#注意,我们通过引用数据帧的列,并不是拷贝出来,仅仅是引用,当我们把引用的数据进行处理时,数据帧也会跟着变化
#使用T转置数据帧
df = df.T
print(df)
#打印
a b c d
year 2000 2010 2005 2004
platform qq weixin weibo taobao
percent 0.71 0.89 0.63 0.82
count NaN NaN NaN NaN
#对数据帧的列和行命名
df.index.name = 'hello'
df.columns.name = 'world'
print(df)
#打印
world year platform percent count
hello
a 2000 qq 0.71 NaN
b 2010 weixin 0.89 NaN
c 2005 weibo 0.63 NaN
d 2004 taobao 0.82 NaN
#数据帧也有values属性,它是一个二维的数组形式组成的:
print(df.values)
#打印
[[2000 'qq' 0.71 nan]
[2010 'weixin' 0.89 nan]
[2005 'weibo' 0.63 nan]
[2004 'taobao' 0.82 nan]]
索引对象
pandas中的索引对象是用于存储轴标签和其他元数据的,在构造的时候,都可以传递一个数组作为索引
obj = pd.Series(range(3), index=['a', 'b', 'c'])
index = obj.index
print(index)
#打印
Index(['a', 'b', 'c'], dtype='object')
print(index[1:])
#打印
Index(['b', 'c'], dtype='object')
#索引是不可变的,所以无法修改
#索引也可以包含重复的标签,也就是说index=['a', 'b', 'c', 'a']这样的
索引对象可以使用的一些方法:
append #将额外的索引对象粘贴到原索引后,产生一个新的索引
difference #计算两个索引的差集
intersection #计算两个索引的交集
union #计算两个索引的并集
isin #表示每一个值是否在传值容器中的布尔数组
delete #将位置i的元素删除,并产生新的索引
insert #在位置i插入元素,并产生新的索引
is_monotonic #如果索引序列递增则返回True
is_unique #如果索引序列唯一则返回True
unique #计算索引的唯一值序列
DataFrame索引选项
# df表示Dataframe的一个实例
#从df中选择单列或列序列:
df[val]
#根据标签选择df中的单行:
df.loc[val]
#根据标签选择df中的多行
df.loc[[val1, val2, val3]]
#根据标签选择df中的单列
df.loc[:, val]
#根据标签选择df中的多列
df.loc[:, [val1, val2, val2]]
#同时选择行和列中的一部分
df.loc[row, col]
#根据整数位置选择单行或多行
df.iloc[where]
#根据整数位置选择单列或多列
df.iloc[:, where]
#根据整数位置选择行和列
df.iloc[where_row, where_col]
#根据行、列标签选择单个标量值
df.at[label_row, label_col]
#根据行、列整数位置选择单个标量值
df.iat[row, col]
#通过标签选择行或列,并按照传递的顺序排序
reindex()
#根据行和列的标签设置单个值
get_value, set_value
在DataFrame的一些加减乘除等方法时,如果直接使用运算符操作,会出现一些NaN值,比如df1中有列‘b’,df2中没有列‘b’那么使用df1+df2的时候,两个数据帧就会合并,但是里面的‘b’列都是NaN值,为了不出现这个情况,可以调用数据帧自带的一些方法,然后传递额外的参数 fill_value,设定需要填充的值替换NaN:
add, radd #加法(+)
sub, rsub #减法(-)
div, rdiv #除法(/)
floordiv, rfloordiv #整除(//)
mul, rmul #乘法(*)
pow, rpow #冥次方(**)
#其中以r开头的函数,是正常函数的副本,表示参数是翻转的,比如说 df.rdiv(1) 等价于 1/df
Dataframe的应用和映射方法
应用和映射的方法分别是:apply、map,下面弄个小示例
#apply 的用法
#np 为 Numpy 组件
import pandas as pd
import numpy as np
df = pd.DataFrame(
np.random.randn(4, 3),
columns=list('bde'),
index=['hello', 'world', 'year', 'month']
)
print(df)
#打印
b d e
hello -0.057626 -0.312814 -0.501929
world -1.574264 0.802262 1.518332
year 0.090305 -0.154119 -2.288428
month -1.296728 -0.508496 -0.290008
fdif = lambda x:x.max() - x.min() #定义个匿名函数,取列中最大值和最小值的差
print(df.apply(fdif)) #将函数应用到 Dataframe 上,可以使用 axis 指定是对行还是列做操作
#打印
b 1.664569
d 1.310758
e 3.806759
dtype: float64
def tempfunc(x):
return pd.Series([x.min(), x.max()], index =['min', 'max'])
print(df.apply(tempfunc)) #还可以将一个特定序列应用到 dataframe 中去
#打印
b d e
min -0.458097 -0.590140 -1.038616
max 0.246472 0.900312 1.667914
#如果想要每个元素做处理,就可以使用 applymap 函数,下面是一个小的尝试
format = lambda x: '%.2f' % x #将浮点数格式化成字符串
print(df.applymap(format))
#打印
b d e
hello 0.47 1.48 -0.60
world 1.15 1.52 -1.07
year -1.39 1.79 -0.33
month 0.06 -1.90 -1.18
#另外applymap可以这么做,是因为Series有一个map方法,因此上面那个操作实际是将每列单独调用了map函数
print(df['e'].map(format)) #单独某个列映射格式化方法
#打印
hello -1.41
world -0.67
year -0.84
month 0.35
Name: e, dtype: object
DataFrame的排序和排名方法:
排序可以使用的 sort_index ,sort_values ,排名可以使用 rank:
ser = pd.Series(range(4), index=list('dabc'))
print(ser)
#打印
d 0
a 1
b 2
c 3
dtype: int64
print(ser.sort_index()) #按照index进行排序
#打印
a 1
b 2
c 3
d 0
dtype: int64
#当然,dataframe 也是可以这么排序的
df = pd.DataFrame([[0, 1, 2, 3], [4, 5, 6, 7]], index=['three', 'one'], columns=list('dabc'))
print(df)
#打印
d a b c
three 0 1 2 3
one 4 5 6 7
print(df.sort_index()) #按照 index 排序
#打印
d a b c
one 4 5 6 7
three 0 1 2 3
print(df.sort_index(axis=1)) #按照 列 排序
#打印
a b c d
three 1 2 3 0
one 5 6 7 4
print(df.sort_index(axis=1, ascending=False)) #按照 列 排序,并且降序排列
#打印
d c b a
three 0 3 2 1
one 4 7 6 5
print(df.sort_values(by='b', ascending=False)) #按照值排序,并且降序,by可以是一个数组
#打印
d a b c
one 4 5 6 7
three 0 1 2 3
#下面使用排名函数rank
df = pd.DataFrame({ #使用字典生成DF
'b': [4.3, 7, -3, 2],
'a': [1, 0, 1, 0],
'c': [-2, 4, 8, -2.5]
})
print(df)
#打印
b a c
0 4.3 1 -2.0
1 7.0 0 4.0
2 -3.0 1 8.0
3 2.0 0 -2.5
print(df.rank(axis='columns')) #使用rank函数对列进行排名,得到的结果是每一项在每列中的具体排名
#打印
b a c
0 3.0 2.0 1.0
1 3.0 1.0 2.0
2 1.0 2.0 3.0
3 3.0 2.0 1.0
#rank带了一个method参数,用来表示根据什么规则来做排名,它的可选项如下:
'average' #默认:在每个组中分配平均排名
'min' #对整个组使用最小排名
'max' #对整个组使用最大排名
'first' #按照值在数据中出现的次序分配排名,主要处理出现相同值的时候,排名会出现小数,如果不希望出现小数,就使用这个模式
'dense' #类似于 ‘min’, 但组间排名总是增加1,而不是一个组中的相等元素的数量
在有时候,Dataframe会出现索引重复的情况,也就是轴索引相等或者同时出现多个,我们可以使用 is_unique 来判断是否有重复的索引存在:df.inde.is_unique, 这个会返回 True 或则 False。
如果索引有重复时,我们取值的时候,就会把所有这个索引的行都会取出来,结果返回的是一个df,而如果只有唯一的索引,返回的就是单个数值或序列。
DataFrame描述性统计的概述和计算
就像我们之前说的apply一样,其实DF中已经有了很多自带的函数,比如求和,求平均值,求方差等等,一些基本统计方法都包含在里面了。