索引和切片

阅读: 5727     评论:4

Series的打印效果,让我们感觉它像个二维表格,实际上它还是一维的,其索引和numpy的一维数组比较类似,但还是有点区别的。

In [23]: se = pd.Series(np.linspace(1,4,5),index=list('abcde'))

In [24]: se
Out[24]:
a    1.00
b    1.75
c    2.50
d    3.25
e    4.00
dtype: float64

In [28]: se['b']    # 利用我们专门指定的索引进行检索
Out[28]: 1.75

In [29]: se[2]  # 实际上默认还有一个从0开始的索引供我们使用
Out[29]: 2.5

In [30]: se[2:4]
Out[30]:
c    2.50
d    3.25
dtype: float64

In [31]: se[['b','a','d']]  # 根据索引顺序,值进行相应的排序,而不是我们认为的按原来的顺序
Out[31]:
b    1.75
a    1.00
d    3.25
dtype: float64

In [32]: se[[1,3]]  # 左闭右开 ,千万不要写成se[1,3]
Out[32]:
b    1.75
d    3.25
dtype: float64

In [33]: se[se>2]
Out[33]:
c    2.50
d    3.25
e    4.00
dtype: float64

In [35]: se['b':'c']  # 什么!居然是左闭右也闭!
Out[35]:
b    1.75
c    2.50
dtype: float64

In [36]: se['b':'c'] = 6  # 这样会修改原Series

In [37]: se
Out[37]:
a    1.00
b    6.00
c    6.00
d    3.25
e    4.00
dtype: float64

注意:如果你的Series是显式的整数索引,那么s[1]这样的取值操作会使用显式索引,而s[1:3]这样的切片操作却会使用隐式索引。Pandas开发人员在历史中为这种问题头疼不已,但没办法,现在还是这么混乱。

In [21]: s = pd.Series(['a','b','c'], index=[1,3,5])

In [22]: s
Out[22]:
1    a
3    b
5    c
dtype: object

In [23]: s[1]
Out[23]: 'a'

In [24]: s[1:3]
Out[24]:
3    b
5    c
dtype: object

对于DataFrame这种二维表格,情况有点不太一样,请务必注意!

核心思维:在DataFrame中,优先按列操作!

In [38]: df = pd.DataFrame(np.arange(16).reshape(4,4),
index=list('abcd'),columns=['one','two','three','four'])

In [39]: df
Out[39]:
   one  two  three  four
a    0    1      2     3
b    4    5      6     7
c    8    9     10    11
d   12   13     14    15

In [40]: df['two']  # 对于DataFrame默认是按列索引
Out[40]:
a     1
b     5
c     9
d    13
Name: two, dtype: int32

In [41]: df['b'] # KeyError,不能直接按行索引

In [43]: df[['one','four']]
Out[43]:
   one  four
a    0     3
b    4     7
c    8    11
d   12    15

In [44]: df[:2]  # 什么!切片的时候居然是按行进行!
Out[44]:
   one  two  three  four
a    0    1      2     3
b    4    5      6     7


In [46]: df['c':'d']  # 注意闭合区间
Out[46]:
   one  two  three  four
c    8    9     10    11
d   12   13     14    15

In [47]: df ['one':'three']  # 试图用列索引来切片,但明显后台按行索引去找了,没找到。
Out[47]:
Empty DataFrame
Columns: [one, two, three, four]
Index: []

In [48]: df < 5
Out[48]:
     one    two  three   four
a   True   True   True   True
b   True  False  False  False
c  False  False  False  False
d  False  False  False  False

In [49]: df[df<5] = 0   # 这一波操作和numpy很类似

In [50]: df
Out[50]:
   one  two  three  four
a    0    0      0     0
b    0    5      6     7
c    8    9     10    11
d   12   13     14    15

是不是觉得好难理解记忆?还是numpy那种索引方式更符合人的思维习惯?没关系,Pandas考虑到了这一点,提供了类似numpy的行+列的索引标签,也就是loc和iloc。这两者差一个字母i。后者是以隐含的整数索引值来索引的,前者则使用你指定的显式的索引来定位值。

In [50]: df
Out[50]:
   one  two  three  four
a    0    0      0     0
b    0    5      6     7
c    8    9     10    11
d   12   13     14    15

In [51]: df.loc['b', ['two','four']]  # 使用显式索引值,用逗号分隔行和列参数
Out[51]:
two     5
four    7
Name: b, dtype: int32

In [53]: df.loc['b':, 'two':'four']  # 切片方式,注意区间
Out[53]:
   two  three  four
b    5      6     7
c    9     10    11
d   13     14    15

In [54]: df.iloc[2, [3, 0, 1]]  # 用隐含的整数索引检索,但是这个打印格式好别扭
Out[54]:
four    11
one      8
two      9
Name: c, dtype: int32

In [55]: df.iloc[2]
Out[55]:
one       8
two       9
three    10
four     11
Name: c, dtype: int32

In [56]: df.iloc[1:,2:3] # 注意区间
Out[56]:
   three
b      6
c     10
d     14

In [57]: df.iloc[:,:3][df.three>5]  # 先切片,再布尔判断
Out[57]:
   one  two  three
b    0    5      6
c    8    9     10
d   12   13     14

提示:老版本的ix标签已经不提倡使用了。


 轴向上删除条目 算术和广播 

评论总数: 4


点击登录后方可评论

df.loc['行', '列']



iloc很好用。



iloc很好用。



因为DataFrame是二维的,类似于数据库表,所以默认按列取值,这很符合常理。