Pandas两个主要数据结构之二——DataFrame
DataFrame是一个表格型数据结构,它含有一组有序的列,每列可以是不用的值类型(数值、字符串、布尔值等)。
DataFrame既有行索引,也有列索引,与其它类似的数据结构相比(如R的data.frame),DataFrame面向行和面向列的操作基本是平衡的。
DataFrame中的数据一般是以一个或者多个二维块存放的(而不是列表、字典或者其它一维数据结构)。
创建DataFrame
-
使用字典创建DataFrame,字典的value类型为list
In [13]: people = {'name': ['a', 'b', 'c', 'd'], ...: 'age': [15, 20, 25, 30], ...: 'gender': ['male', 'female', 'female', 'male']} In [14]: df = pd.DataFrame(people) In [15]: df Out[15]: name age gender 0 a 15 male 1 b 20 female 2 c 25 female 3 d 30 male
可以使用参数
columns
来改变列的顺序In [16]: df_test_columns = pd.DataFrame(people, columns=['gender', 'name', 'age']) In [17]: df_test_columns Out[17]: gender name age 0 male a 15 1 female b 20 2 female c 25 3 male d 30
-
和Series一样,如果传入的列在数据中找不到的话,就会产生NA值
In [32]: df2 = pd.DataFrame(data, columns=['pop', 'state', 'year', 'debt'], ...: index=['one', 'two', 'three', 'four', 'five']) In [33]: df2 Out[33]: pop state year debt one 1.5 Ohio 2000 NaN two 1.7 Ohio 2001 NaN three 3.6 Ohio 2002 NaN four 2.4 Nevada 2001 NaN five 3.9 Nevada 2002 NaN In [34]: df2.columns Out[34]: Index(['pop', 'state', 'year', 'debt'], dtype='object')
在实际使用中,更普遍的情况是读取表格来生成DateFrame,所以就不写太多生成DateFrame的方法了。
DataFrame的列访问与处理
-
获取DataFrame列的两种方式:字典标记形式、属性形式
In [35]: df2.state Out[35]: one Ohio two Ohio three Ohio four Nevada five Nevada Name: state, dtype: object In [36]: df2['state'] Out[36]: one Ohio two Ohio three Ohio four Nevada five Nevada Name: state, dtype: object
-
通过赋值(一个值或一组值)的方式进行修改某列的值
In [37]: df2.debt = 16.5 In [38]: df2 Out[38]: pop state year debt one 1.5 Ohio 2000 16.5 two 1.7 Ohio 2001 16.5 three 3.6 Ohio 2002 16.5 four 2.4 Nevada 2001 16.5 five 3.9 Nevada 2002 16.5
In [45]: df2['debt'] = np.arange(5.) In [46]: df2 Out[46]: pop state year debt one 1.5 Ohio 2000 0.0 two 1.7 Ohio 2001 1.0 three 3.6 Ohio 2002 2.0 four 2.4 Nevada 2001 3.0 five 3.9 Nevada 2002 4.0
将列表或者数组赋值给某一列时,其长度必须与DataFrame相匹配。如果赋值的是Series,就会精确匹配DataFrame的索引,所有空位都会补上缺失值。
In [47]: val = pd.Series([-1.2, -1.5, -1.7], index=['two', 'four', 'five']) In [48]: df2.debt = val In [49]: df2 Out[49]: pop state year debt one 1.5 Ohio 2000 NaN two 1.7 Ohio 2001 -1.2 three 3.6 Ohio 2002 NaN four 2.4 Nevada 2001 -1.5 five 3.9 Nevada 2002 -1.7
-
为不存在的列赋值会创建新列。
In [55]: df2['eastern'] = df2.state == 'Ohio' In [56]: df2 Out[56]: pop state year debt eastern one 1.5 Ohio 2000 NaN True two 1.7 Ohio 2001 -1.2 True three 3.6 Ohio 2002 NaN True four 2.4 Nevada 2001 -1.5 False five 3.9 Nevada 2002 -1.7 False
-
删除某列。可以使用del关键字,也可以使用DataFrame.drop()
In [57]: del df2['eastern'] In [58]: df2 Out[58]: pop state year debt one 1.5 Ohio 2000 NaN two 1.7 Ohio 2001 -1.2 three 3.6 Ohio 2002 NaN four 2.4 Nevada 2001 -1.5 five 3.9 Nevada 2002 -1.7 In [65]: df2['debt'].loc['two'] Out[65]: -1.2
DataFrame.drop(labels=None,axis=0, index=None, columns=None, inplace=False)
参数含义:
- labels:要删除的行或列,用列表给出
- axis:默认为 0,指要删除的是行,删除列时需指定 axis 为 1
- index :直接指定要删除的行,删除多行可以使用列表作为参数
columns:直接指定要删除的列,删除多列可以使用列表作为参数
inplace: 默认为 False,该删除操作不改变原数据;inplace = True 时,改变原数据
通过索引方式返回的列只是数据的视图,并不是副本。因此对返回的Series所做的任何就地修改都会直接作用到源DataFrame上。通过Series的copy方法,可以显式的复制列。
这个地方极其容易出现SettingwithCopyWarning警告,具体的原因及解决办法参考:Pandas 中 SettingwithCopyWarning 的原理和解决方案
DataFrame的行访问
DateFrame对行有两个操作符:iloc和loc。
其中iloc对index进行索引,loc对列名进行索引,特别要注意的是当列名为0,1,2,3,...的数字索引时,两者都可以正常运行,但是本质上还是有区别的。
-
index不是0,1,2,3的数字索引
In [10]: df1 = pd.DataFrame(people, index=['w', 'x', 'y', 'z']) In [11]: df1 Out[11]: name age gender w a 15 male x b 20 female y c 25 female z d 30 male In [12]: df1.iloc[0] Out[12]: name a age 15 gender male Name: w, dtype: object In [13]: df1.loc['w'] Out[13]: name a age 15 gender male Name: w, dtype: object
-
index不是0,1,2,3这类的数字索引
In [15]: df2 = pd.DataFrame(people, index=range(1,5)) In [16]: df2 Out[16]: name age gender 1 a 15 male 2 b 20 female 3 c 25 female 4 d 30 male In [18]: df2.iloc[0] Out[18]: name a age 15 gender male Name: 1, dtype: object In [19]: df2.loc[1] Out[19]: name a age 15 gender male Name: 1, dtype: object
可以看见,在index为数字索引时,两者确实都可以成功索引,但是其实质索引方式仍旧是不一样的。
iloc索引的是index次序,即是否是第0个,而loc索引的是index值是否等于1。