重新索引
pandas对象的一个重要方法,其作用是创建一个适应新索引的新对象。
reindex在Series上的应用
In [3]: obj = Series([4.5, 7.2, -5.3, 3.6], index=['d','b','a','c'])
In [4]: obj
Out[4]:
d 4.5
b 7.2
a -5.3
c 3.6
dtype: float64
In [5]: obj2 = reindex(['a', 'b', 'c', 'd', 'e'])
In [6]: obj2 = obj.reindex(['a', 'b', 'c', 'd', 'e'])
In [7]: obj2
Out[7]:
a -5.3
b 7.2
c 3.6
d 4.5
e NaN #如果新索引之前不存在,那么它的值就为缺失值
dtype: float64
Series的reindex函数将会根据新索引对数据重新排列,并且返回一个新的Series对象。如果某个索引不存在,那么它对应的值就为缺失值。
如果想要对缺失值进行补充,那么也有下面这几个方法:
In [8]: obj.reindex(['a', 'b', 'c', 'd', 'e'],fill_value=0)
Out[8]:
a -5.3
b 7.2
c 3.6
d 4.5
e 0.0
dtype: float64
这里直接预设了填充值为0,意味着该Series中所有的空缺值都将被替换成0
另外一种方法是:
obj3 = Series(['blue','purple','yellow'], index=[0, 2, 4])
In [10]: obj3.reindex(range(6), method='ffill') # 'ffill'为前向填充,缺失值将前一位数据作为填充值,反之就是后向填充'bfill'
Out[10]:
0 blue
1 blue
2 purple
3 purple
4 yellow
5 yellow
dtype: object
In [11]: obj3
Out[11]:
0 blue
2 purple
4 yellow
dtype: object
如果不想把填充值固定,也可以考虑使用method
选项,它可以依据前后数据做填充处理。
reindex在DataFrame上的应用
reindex不单可以修改行索引,也可以修改DataFrame的列索引
In [14]: frame = DataFrame(np.arange(9).reshape((3, 3)), index=['a', 'c', 'd'], columns=['Ohio', 'Texas', 'California'])
In [15]: frame
Out[15]:
Ohio Texas California
a 0 1 2
c 3 4 5
d 6 7 8
In [16]: frame2 = frame.reindex(['a','b','c','d'])
In [17]: frame2
Out[17]:
Ohio Texas California
a 0.0 1.0 2.0
b NaN NaN NaN
c 3.0 4.0 5.0
d 6.0 7.0 8.0
同Series,在修改行索引的时候出现索引不存在的情况就会引入缺失值NaN
。
如何重新索引列:
In [18]: states = ['Texas', 'Utah', 'California']
In [19]: frame.reindex(columns=states)
Out[19]:
Texas Utah California
a 1 NaN 2
c 4 NaN 5
d 7 NaN 8
method
插值能否同时对行列产生作用
In [38]: frame.reindex(index=['a','b','c','d'],method='ffill', columns = ['Texas','Utah','California'])
>>> index must be monotonic increasing or decreasing
按照书中的写法,发现在现在这个版本中已经不适用了,会出现错误。在这个方法中如果存在插值属性method
,那行索引和列索引都将会被补充,但是在例子中列索引并不像行索引一样是有序的,所以才会出现这的错误。
In [39]: frame.reindex(index=['a','b','c','d'], columns = ['Texas','Utah','California']).ffill()
Out[39]:
Texas Utah California
a 1.0 NaN 2.0
b 1.0 NaN 2.0
c 4.0 NaN 5.0
d 7.0 NaN 8.0
改成这种写法就可以了。
丢弃指定轴上的项
丢弃指定轴上的项drop()
在清理数据中是一个非常重要的功能。
drop
函数在Series上的应用:
In [40]: obj = Series(np.arange(5.), index=['a','b','c','d','e'])
In [41]: new_obj = obj.drop('c')
In [42]: new_obj
Out[42]:
a 0.0
b 1.0
d 3.0
e 4.0
dtype: float64
当然也可以同时删除多个项:
In [43]: obj.drop(['d','c'])
Out[43]:
a 0.0
b 1.0
e 4.0
dtype: float64
drop
函数在DataFrame上的应用
In [45]: data = DataFrame(np.arange(16).reshape(4,4), index=['Ohio','Colorado','Utah','New York'], columns=['one','two','thre
...: e','four'])
In [46]: data
Out[46]:
one two three four
Ohio 0 1 2 3
Colorado 4 5 6 7
Utah 8 9 10 11
New York 12 13 14 15
In [47]: data.drop(['Colorado', 'Ohio'])
Out[47]:
one two three four
Utah 8 9 10 11
New York 12 13 14 15
如果是删除行索引,同Series我们可以直接删除任意一个或多个轴上的值。
如果要删除列索引
In [50]: data.drop('two')
>>> KeyError: "['two'] not found in axis"
它是不能直接删除的,会出现报错。意思是在默认的轴上并没有发现two
这个索引。
因为dop
函数默认的轴是横向的,如果想要删除某个列就必须告诉它我要删除纵向的轴。可通过下面这个方式:
In [49]: data.drop('two', axis=1)
Out[49]:
one three four
Ohio 0 2 3
Colorado 4 6 7
Utah 8 10 11
New York 12 14 15
In [51]: data.drop(['two','four'], axis=1)
Out[51]:
one three
Ohio 0 2
Colorado 4 6
Utah 8 10
New York 12 14
索引、选区和过滤
Series最基本的索引:
In [52]: obj = Series(np.arange(4), index=['a','b','c','d'])
In [53]: obj['b']
Out[53]: 1
In [54]: obj[1]
Out[54]: 1
Series的切片索引、选取和过滤:
In [55]: obj[2:4] #切片索引
Out[55]:
c 2
d 3
dtype: int64
In [56]: obj[[1, 3]] # 选取索引
Out[56]:
b 1
d 3
dtype: int64
In [57]: obj[obj < 2] #过滤
Out[57]:
a 0
b 1
dtype: int64
这里还有一种比较好玩的切片选取方式,就是利用标签来切片:
In [58]: obj['b':'c']
Out[58]:
b 1
c 2
dtype: int64
如果是用标签来切片的情况下,它与Python传统切片不同,切片末端的数据也会被选取到。
DataFrame的切片索引、选取和过滤
DataFrame最基本的索引:
In [61]: data = DataFrame(np.arange(16).reshape((4,4)), index=['Ohio','Colorado','Utah','New York'], columns=['one','two','th
...: ree','four'])
In [62]: data
Out[62]:
one two three four
Ohio 0 1 2 3
Colorado 4 5 6 7
Utah 8 9 10 11
New York 12 13 14 15
In [63]: data['two']
Out[63]:
Ohio 1
Colorado 5
Utah 9
New York 13
Name: two, dtype: int64
In [64]: data[['three','two']]
Out[64]:
three two
Ohio 2 1
Colorado 6 5
Utah 10 9
New York 14 13
DataFrame的切片和过滤:
In [65]: data[:2] #切片过程中,DataFrame默认也是选取行
Out[65]:
one two three four
Ohio 0 1 2 3
Colorado 4 5 6 7
布尔型数组也是默认选取行
In [66]: data[data['three'] > 5]
Out[66]:
one two three four
Colorado 4 5 6 7
Utah 8 9 10 11
New York 12 13 14 15
通过布尔型DataFrame
进行选取:
In [69]: data < 5
Out[69]:
one two three four
Ohio True True True True
Colorado True False False False
Utah False False False False
New York False False False False
再看一下data
里有哪些数据是<5
的
In [70]: data[data < 5]
Out[70]:
one two three four
Ohio 0.0 1.0 2.0 3.0
Colorado 4.0 NaN NaN NaN
Utah NaN NaN NaN NaN
New York NaN NaN NaN NaN
把这些值全都改成0:
In [71]: data[data < 5] = 0
In [72]: data
Out[72]:
one two three four
Ohio 0 0 0 0
Colorado 0 5 6 7
Utah 8 9 10 11
New York 12 13 14 15
进阶选取,先选取列数据再选取行数据:
在新版本pandas中,复杂的选取方式我们可以通过以下2种方式loc
函数和iloc
函数。
loc函数
loc
函数有以下多种方式来选取以及过滤数据的:
- 标签类型
- 切片
- 布尔值/逻辑判断
它的语法为data.loc[<row selection>, <column selection>]
标签类型
In [75]: data.loc['Colorado',['two','three']]
Out[75]:
two 5
three 6
Name: Colorado, dtype: int64
In [101]: data.loc[:'Utah', 'two']
Out[101]:
Ohio 0
Colorado 5
Utah 9
Name: two, dtype: int64
切片
In [112]: data.loc['Utah',:'two']
Out[112]:
one 8
two 9
Name: Utah, dtype: int64
布尔值/逻辑判断
In [116]: data.three > 5
Out[116]:
Ohio False
Colorado True
Utah True
New York True
Name: three, dtype: bool
In [115]: data.loc[data.three > 5]
Out[115]:
one two three four
Colorado 0 5 6 7
Utah 8 9 10 11
New York 12 13 14 15
由于data.three > 5
最终会返回一个Series对象,DataFrame会通过这个布尔型Series来相互匹配选取布尔值True
对应的数据最终得到了过滤后的数据。
iloc函数
iloc
函数则是基于整数参数来获取数据的,它的语法为data.loc[<row selection>, <column selection>]
In [96]: data.iloc[2]
Out[96]:
one 8
two 9
three 10
four 11
Name: Utah, dtype: int64
单独选择了第三行,返回Utah
的Series
对象。因为参数中是一个单独的整数,所以iloc
函数会返回Series
对象。
如果想要它返回DataFrame
对象,可以这么写:
In [119]: data.iloc[[2]]
Out[119]:
one two three four
Utah 8 9 10 11
在iloc
函数中,传入一个数组就可以了。
行列混合选取:
In [117]: data.iloc[[0,1,2],[0,1]]
Out[117]:
one two
Ohio 0 0
Colorado 0 5
Utah 8 9
选取最后一行:
In [120]: data.iloc[-1]
Out[120]:
one 12
two 13
three 14
four 15
Name: New York, dtype: int64