DataFrame是二维的数据结构,可以认为是个数据框,也可以认为DataFrame就是数据表格,类似于Excel,有行与列,行有行标签(如1、2、3...),列有列标签(如A、B、C...)。
DataFrame是具有二维标签轴(行和列)且尺寸可变的、强大多样的表格数据结构。算术操作在行和列标签上对齐。可以看作是一个类似于字典对象的容器。
DataFrame对象的完整调用形式如下:
pandas.
DataFrame
(data=None, index=None, columns=None, dtype=None, copy=False)
data:用于创建DataFrame的数据,可以numpy的ndarray、数据字典、或其它的DataFrame。字典又可以包含Series、数组、常量和其它列表。
index:索引对象或数组。用于指定DataFrame数据的行标签,如果没有指定黙认就是RangeIndex对象作为Index。
columns:索引或数组。用于生成DataFrame数据的列标签,如果列标签没有指定黙认就是RangeIndex。
dtype:数据类型,黙认为None,自动推断。
copy:布尔类型,黙认为False,如果为True,返回的是输入数据data的一个副本。
详情参见:http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.html
示例1:
>>> arr01 = [['Tom','Merry','John'],[76,98,100]] # 先创建一个二维数组
>>> df01 = DataFrame(arr01) # 根据二维数组创建DataFrame
>>> df01 # 行与列标签索引都是RangeIndex
0 1 2
0 Tom Merry John
1 76 98 100
由上代码可知,生成了一个2行3列的表格,由于没有指定Index,所以黙认是RangeIndex对象,也就是从0开始依次递增的自然数(0,1,2,...)。
示例2:改变一下二维数据结构
>>> arr02 = [['Tom',76],['Merry',98],['John',100]]
>>> df02 = DataFrame(arr02)
>>> df02
0 1
0 Tom 76
1 Merry 98
2 John 100
DataFrame比二维数据更像表格。
再来看看它们的values与index属性:
>>> df01.values # 就是个二维ndarray数组
array([['Tom', 'Merry', 'John'],
[76, 98, 100]], dtype=object)
>>> df02.values # 二维ndarray数组
array([['Tom', 76L],
['Merry', 98L],
['John', 100L]], dtype=object)
>>> df01.index
RangeIndex(start=0, stop=2, step=1)
>>> df02.index
RangeIndex(start=0, stop=3, step=1)
索引类型都是RangeIndex对象。如果用Jupyter NoteBook显示DataFrame会好看些。
通过Index指定行索引标签:
>>> df01 = DataFrame(arr01,index=['a','b'])
>>> df01 # 行标签为a和b
0 1 2
a Tom Merry John
b 76 98 100
行标签还可以指定多个:
>>> df01 = DataFrame(arr01,index=[['a','b'],['aa','bb']])
>>> df01 # 两个行标签
0 1 2
a aa Tom Merry John
b bb 76 98 100
多个行标签,在以后生成非常复杂的表格结构时非常有用。
列标签是通过columns指定的,如下所示:
>>> df01 = DataFrame(arr01,index=['a1','a2'],columns=['b1','b2','b3'])
>>> df01
b1 b2 b3
a1 Tom Merry John
a2 76 98 100
以上代码,一目了然。
示例:
>>> data = {"apart":['1001','1002','1003','1001'],"profits":[567.87,987.87,873,498.87],"year":[2001,2001,2001,2000]}
>>> data
{'year': [2001, 2001, 2001, 2000], 'profits': [567.87, 987.87, 873, 498.87], 'apart': ['1001', '1002', '1003', '1001']} >>> df = DataFrame(data)
>>> df
apart profits year
0 1001 567.87 2001
1 1002 987.87 2001
2 1003 873.00 2001
3 1001 498.87 2000
通过字典创建DataFrame时,字典的键(Key)是作为DataFrame的列标签,在以上代码中行标签自动生成RangeIndex,当然可以通过Index参数指定。
上面的代码中,字典的值是一个列表,也可以是ndarray和Series类型。
1、索引与设置数据
>>> df
apart profits year
0 1001 567.87 2001
1 1002 987.87 2001
2 1003 873.00 2001
3 1001 498.87 2000
>>> df['apart'][0] # 取值
'1001'
>>> df['apart'][0] = '1000' # 赋值
>>> df
apart profits year
0 1000 567.87 2001
1 1002 987.87 2001
2 1003 873.00 2001
3 1001 498.87 2000
上面的DataFrame索引方式是通过列行来索引的,注意,第1个方括号选择的是DataFrame的列标签,第2个方括号选择是DataFrame行标签。
2、切片的索引与赋值
>>> df['apart'][0:] # 选择第1列,这样后面一个方括号里的可以不写
0 1000
1 1002
2 1003
3 1001
Name: apart, dtype: object
>>> df['apart'][0:2] # 选择第1列,第1、2行,注意,不包含右边界
0 1000
1 1002
Name: apart, dtype: object
>>> df['apart'][0:2] = 1002 # 将第1列的第1行与第2行设置为1002
>>> df
apart profits year
0 1002 567.87 2001
1 1002 987.87 2001
2 1003 873.00 2001
3 1001 498.87 2000
>>> df[['apart','profits']] # 选择多列
apart profits
0 1002 567.87
1 1002 987.87
2 1003 873.00
3 1001 498.87
>>> df[0:2] # 选择第1行与第2行
apart profits year
0 1002 567.87 2001
1 1002 987.87 2001
>>> df[0:2]['apart'] # 选择第1、2行与apart列
0 1002
1 1002
Name: apart, dtype: object
感觉有点晕了,怎么第一个方括号又可以选行,又可以选列。如果列没有指定字符串标签而是黙认的RangIndex会怎么样呢?df[0:2][1:]这个东西会选择什么呢?你运行结果,就更懵了,不信你试~
3、loc,在知道列名字的情况下,df.loc[index,column] 选取指定行,列的数据
>>> df
apart profits year
0 1002 567.87 2001
1 1002 987.87 2001
2 1003 873.00 2001
3 1001 498.87 2000
>>> df.loc[0,'apart']
1002
>>> df.loc[0:,'apart']
0 1002
1 1002
2 1003
3 1001
Name: apart, dtype: object
>>> df.loc[df['apart']=='1003','profits'] # 选择apart列等于1003的行与profits列的值
2 873.0
Name: profits, dtype: float64
4、iloc,在column name特别长或者index是时间序列等各种不方便输入的情况下,可以用iloc (i = index), iloc完全用数字来定位 iloc[row_index, column_index]
>>> df.iloc[0,0]
1002
>>> df.iloc[0,2:]
year 2001
Name: 0, dtype: object
>>> df.iloc[0,1:]
profits 567.87
year 2001
Name: 0, dtype: object
>>> df.iloc[0:2,1:]
profits year
0 567.87 2001
1 987.87 2001
我们之前提过,在指定标签的情况下,其实轴底层还是有一个RandIndex索引的。
通过Series或DataFrame的index属性可以重建行索引,通过DataFrame的columns属性可以重建列索引,前面也已经举过示例了,这里再看一下:
>>> import pandas as pd # 这里只引用了pandas,没有引用DataFrame所以要通过pd.DataFrame调用
>>> df = pd.DataFrame({'C++':[50,50,20],'Java':[20,30,40],'Python':[10,20,30]})
>>> df
C++ Java Python
0 50 20 10
1 50 30 20
2 20 40 30
>>> df.index = ['A','B','C'] # 改变行标签
>>> df
C++ Java Python
A 50 20 10
B 50 30 20
C 20 40 30
>>> df.columns = ['Java','Python','C++'] # 改变列标签
>>> df
Java Python C++
A 50 20 10
B 50 30 20
C 20 40 30