第五篇 pandas??

pandas含有使数据清洗和分析?作变得更快更简单的数据结构和操作?具。
pandas经常和其它?具?同使?,如数值计算?具NumPy和SciPy,分析库
statsmodels和scikit-learn,和数据可视化库matplotlib。pandas
是基于NumPy数组构建的,特别是基于数组的函数和不使?for循环的数据处理。

pandas与NumPy的不同:pandas采?了?量的NumPy编码?格,不同是pandas是专?为处理表格和混杂数据设计的。?NumPy更适合处理统?的数值数组数据。

从2010年pandas开源以来,pandas逐渐成?为?个?常?的库,应?于许多真实案例。开发者社区已经有了800个独?的贡献者。

pandas导?约定:import pandas as pd
Series和DataFrame?的次数多,可将其引?本地命名空间中会更?便:
from pandas import Series, DataFram

一、pandas的数据结构介绍
两个主要数据结构:Series和DataFrame。虽不能解决所有问题,但它们为?多数应?提供了?种可靠的、易于使?的基础。

1、Series
Series是?种类似于?维数组的对象,它由?组数据(各种NumPy数据类型)以及?组与之相关的数据标签(即索引)组成。仅由?组数据即可产?最简单的Series:
obj = pd.Series([4, 7, -5, 3])
obj       # 输出如下:包含元素索引、元素,以及数据类型
0    4
1    7
2    -5
3    3
dtype: int64
Series的字符串表现形式为:索引在左边,值在右边。未指定索引,于是会?动创建?个0到N-1(N为数据的?度)的整数型索引。可通过Series 的values和index属性获取其数组表示形式和索引对象:
obj.values      # 输出:array([ 4, 7, -5, 3], dtype=int64)
obj.index       # 输出:RangeIndex(start=0, stop=4, step=1),(like range(4))

通常,希望所创建的Series带有?个可以对各个数据点进?标记的索引:
obj2 = pd.Series([4, 7, -5, 3], index=[‘d‘, ‘b‘, ‘a‘, ‘c‘])  # 指定行索引
obj2   # 输出如下:
d    4
b    7
a    -5
c    3
dtype: int64
obj2.index # 输出:Index([‘d‘, ‘b‘, ‘a‘, ‘c‘], dtype=‘object‘)
与普通NumPy数组相?,你可以通过索引的?式选取Series中的单个或?组值:
obj2[‘a‘]      # 输出:-5
obj2[‘d‘] = 6     # 设定索引‘d‘的值
obj2[[‘c‘, ‘a‘, ‘d‘]]    # 输出:(注意参数是列表)
c    3
a    -5
d    6
dtype: int64
[‘c‘, ‘a‘, ‘d‘]是索引列表,即使它包含的是字符串?不是整数。

使?NumPy函数或类似NumPy的运算(如根据布尔型数组进?过滤、标量乘法、应?数学函数等)都会保留索引值的链接:
obj2[obj2 > 0]     # 输出:(布尔运算)
d    6
b    7
c    3
dtype: int64
obj2 * 2        # 输出:(标量乘法)
d    12
b    14
a    -10
c    6
dtype: int64
np.exp(obj2)     # 输出:(运用于数学函数)
d    403.428793
b    1096.633158
a    0.006738
c    20.085537
dtype: float64

还可以将Series看成是?个定?的有序字典,因为它是索引值到数据值的?个映射。它可以?在许多原本需要字典参数的函数中:
‘b‘ in obj2    # 输出:True
‘e‘ in obj2    # 输出:False

如果数据被存放在?个Python字典中,也可以直接通过这个字典来创建Series:
sdata = {‘Ohio‘: 35000, ‘Texas‘: 71000, ‘Oregon‘: 16000, ‘Utah‘: 5000}
obj3 = pd.Series(sdata)
obj3        # 输出:
Ohio    35000
Texas   71000
Oregon  16000
Utah    5000
dtype: int64
如果只传??个字典,则结果Series中的索引就是原字典的键(有序排列)。你可以传?排好序的字典的键以改变顺序:
states = [‘California‘, ‘Ohio‘, ‘Oregon‘, ‘Texas‘]
obj4 = pd.Series(sdata, index=states)
obj4        # 输出:
California    NaN
Ohio      35000.0
Oregon      16000.0
Texas      71000.0
dtype: float64
在这个例?中,sdata中跟states索引相匹配的那3个值会被找出来并放到相应的位置上,但由于"California"所对应的sdata值找不到,所以其结果就为NaN(即“?数字”(not a number),在pandas中,它?于表示缺失或NA值)。因为‘Utah’不在states中,它被从结果中除去。

使?缺失(missing)或NA表示缺失数据。pandas的isnull和notnull函数可?于检测缺失数据:
pd.isnull(obj4)      # 检测obj4中哪些数据缺失
California    True
Ohio      False
Oregon       False
Texas       False
dtype: bool
pd.notnull(obj4)     # 检测obj4中哪些数据不缺失
California    False
Ohio      True
Oregon       True
Texas     True
dtype: bool
Series也有类似的实例?法:
obj4.isnull()       # 检测obj4中哪些数据缺失,obj4.notnull()方法检测数据不缺失
California    True
Ohio      False
Oregon       False
Texas       False
dtype: bool

对于许多应???,Series最重要的?个功能是,它会根据运算的索引标签?动对?数据:
obj3      # 输出:
Ohio      35000
Texas     71000
Oregon       16000
Utah      5000
dtype: int64
obj4      # 输出:
California    NaN
Ohio      35000.0
Oregon      16000.0
Texas         71000.0
dtype: float64
obj3 + obj4     # 输出:
California    NaN
Ohio      70000.0
Oregon       32000.0
Texas      142000.0
Utah      NaN
dtype: float64
该功能类似于数据库的join的操作

Series对象本身及其索引都有?个name属性,该属性跟pandas其他的关键功能关系?常密切:
obj4.name = ‘population‘     # 设置Series对象本身的name属性
obj4.index.name = ‘state‘     # 设置Series对象索引的name属性
obj4      # 输出如下:
state
California    NaN
Ohio      35000.0
Oregon      16000.0
Texas       71000.0
Name: population, dtype: float64

Series的索引可以通过赋值的?式就地修改:
obj     # obj的原始索引及数据
0    4
1    7
2    -5
3    3
dtype: int64
obj.index = [‘Bob‘, ‘Steve‘, ‘Jeff‘, ‘Ryan‘]   # 修改obj的索引
obj     # obj修改后的索引及数据,输出如下所示:
Bob       4
Steve    7
Jeff      -5
Ryan    3
dtype: int64

2、DataFrame

DataFrame是?个表格型的数据结构,它含有?组有序的列,每列可以是不同的值类型(数值、字符串、布尔值等)。DataFrame既有?索引也有列索引,它可以被看做由Series组成的字典(共?同?个索引)。DataFrame中的数据是以?个或多个?维块存放的(?不是列表、字典或别的?维数据结构)。

虽然DataFrame是以?维结构保存数据的,仍可以将其表示为更?维度的数据(层次化索引的表格型结构,这是pandas中许多?级数据处理功能的关键要素)。

创建DataFrame的办法很多,最常?的?种是直接传??个由等?列表或NumPy数组组成的字典:
data = {‘state‘: [‘Ohio‘, ‘Ohio‘, ‘Ohio‘, ‘Nevada‘, ‘Nevada‘, ‘Nevada‘],
    ‘year‘: [2000, 2001, 2002, 2001, 2002, 2003],
    ‘pop‘: [1.5, 1.7, 3.6, 2.4, 2.9, 3.2]}
frame = pd.DataFrame(data)
结果DataFrame会?动加上索引(跟Series?样),且全部列会被有序排列:
frame      # 输出如下:
      state          year    pop
0    Ohio         2000    1.5
1    Ohio         2001    1.7
2    Ohio      2002    3.6
3    Nevada    2001    2.4
4    Nevada    2002    2.9
5    Nevada    2003    3.2
使?Jupyter notebook,pandas DataFrame对象会以对浏览器友好的HTML表格的?式呈现。
对于特别?的DataFrame,head?法会选取前五?:
frame.head()     # 输出如下:
    state     year    pop
0    Ohio    2000    1.5
1    Ohio    2001    1.7
2    Ohio    2002    3.6
3    Nevada    2001    2.4
4    Nevada    2002    2.9
如果指定了列序列,则DataFrame的列就会按照指定顺序进?排列:
pd.DataFrame(data, columns=[‘year‘, ‘state‘, ‘pop‘])
     year    state    pop
0    2000    Ohio    1.5
1    2001    Ohio    1.7
2    2002    Ohio    3.6
3    2001    Nevada     2.4
4    2002    Nevada     2.9
5    2003    Nevada     3.2
如果传?的列在数据中找不到,就会在结果中产?缺失值:
frame2 = pd.DataFrame(data, columns=[‘year‘, ‘state‘, ‘pop‘, ‘debt‘],
            index=[‘one‘, ‘two‘, ‘three‘, ‘four‘,‘five‘, ‘six‘])
frame2      # 输出如下:
      year    state    pop   debt
one    2000   Ohio    1.5    NaN
two    2001    Ohio    1.7    NaN
three    2002    Ohio    3.6    NaN
four   2001    Nevada     2.4    NaN
five      2002    Nevada     2.9    NaN
six    2003    Nevada   3.2    NaN
frame2.columns     # 输出: Index([‘year‘, ‘state‘, ‘pop‘, ‘debt‘], dtype=‘object‘)
通过类似字典标记的?式或属性的?式,可以将DataFrame的列获取为?个Series:
frame2[‘state‘]     # 通过字典的方式获取列
one    Ohio
two    Ohio
three     Ohio
four    Nevada
five     Nevada
six      Nevada
Name: state, dtype: object

frame2.year     # 通过属性的方式获取
one    2000
two    2001
three    2002
four    2001
five    2002
six     2003
Name: year, dtype: int64
注意:IPython提供了类似属性的访问(即frame2.year)和tab补全。frame2[column]适?于任何列的名,但是frame2.column只有在列名是?个合理的Python变量名时才适?。返回的Series拥有原DataFrame相同的索引,且其name属性也已经被相应地设置好了。

?也可以通过位置或名称的?式进?获取,?如?loc属性:
frame2.loc[‘three‘]   # 输出如下:
year    2002
state    Ohio
pop     3.6
debt    NaN
Name: three, dtype: object

列可以通过赋值的?式进?修改。例如,可以给那个空的"debt"列赋上?个标量值或?组值:
frame2[‘debt‘] = 16.5     # 赋值一个标量值
frame2        # 输出如下:
      year    state    pop    debt
one    2000    Ohio    1.5    16.5
two    2001    Ohio     1.7    16.5
three     2002    Ohio    3.6    16.5
four    2001    Nevada     2.4    16.5
five    2002    Nevada      2.9    16.5
six     2003    Nevada      3.2    16.5
frame2[‘debt‘] = np.arange(6.)   # 赋值一组值
frame2        # 输出如下:
      year    state    pop    debt
one    2000    Ohio    1.5    0.0
two    2001    Ohio    1.7    1.0
three    2002    Ohio    3.6    2.0
four    2001    Nevada    2.4    3.0
five    2002    Nevada     2.9    4.0
six     2003    Nevada     3.2    5.0

将列表或数组赋值给某个列时,其?度必须跟DataFrame的?度相匹配。如果赋值的是?个Series,就会精确匹配DataFrame的索引,所有的空位都将被填上缺失值:例如:
val = pd.Series([-1.2, -1.5, -1.7], index=[‘two‘, ‘four‘, ‘five‘])
frame2[‘debt‘] = val      # 精确匹配索引
frame2       # 输出如下:
      year    state   pop    debt
one    2000    Ohio    1.5    NaN
two    2001    Ohio    1.7    -1.2
three    2002    Ohio    3.6    NaN
four      2001    Nevada     2.4   1.5
five    2002    Nevada     2.9    -1.7
six     2003    Nevada     3.2    NaN

为不存在的列赋值会创建出?个新列。关键字del?于删除列。作为del的例?,我先添加?个新的布尔值的列,判断state是否为‘Ohio‘:
frame2[‘eastern‘] = frame2.state == ‘Ohio‘
frame2        # 输出如下:
      year    state   pop    debt    eastern
one    2000    Ohio    1.5    NaN    True
two    2001    Ohio    1.7    -1.2      True
three    2002    Ohio    3.6    NaN    True
four   2001    Nevada     2.4  -1.5       False
five    2002    Nevada     2.9    -1.7    False
six     2003    Nevada     3.2    NaN    False
注意:不能?frame2.eastern创建新的列。
del?法可以?来删除这列:
del frame2[‘eastern‘]
frame2.columns     # 输出:Index([‘year‘, ‘state‘, ‘pop‘, ‘debt‘], dtype=‘object‘)
注意:通过索引?式返回的列只是相应数据的视图?已,并不是副本。因此,对返回的Series所做的任何就地修改全都会反映到源DataFrame上。通过Series的copy?法即可指定复制列。

另?种常?的数据形式是嵌套字典:
pop = {‘Nevada‘: {2001: 2.4, 2002: 2.9}, ‘Ohio‘: {2000: 1.5, 2001: 1.7, 2002: 3.6}}
如果嵌套字典传给DataFrame,pandas就会被解释为:外层字典的键作为列索引,内层键则作为?索引:
frame3 = pd.DataFrame(pop)   # 将字典pop转换为DataFrame
frame3        # 输出:
    Nevada   Ohio
2000    NaN    1.5
2001    2.4      1.7
2002    2.9      3.6
也可以使?类似NumPy数组的?法,对DataFrame进?转置(交换?和列):
frame3.T
      2000    2001    2002
Nevada    NaN    2.4    2.9
Ohio      1.5    1.7    3.6
内层字典的键会被合并、排序以形成最终的索引。如果明确指定了索引,则不会这样:
pd.DataFrame(pop, index=[2001, 2002, 2003])   # 要报错:AttributeError: ‘list‘ object has no attribute ‘astype‘
frame55 = pd.DataFrame(pop)        # 先将pop数据转换为DataFrame数据后可指定索引
pd.DataFrame(frame55, index=[2001, 2002, 2003])   # 这样指定索引排序不会报错
    Nevada   Ohio
2001    2.4    1.7
2002    2.9    3.6
2003    NaN    NaN

由Series组成的字典差不多也是?样的?法:
pdata = {‘Ohio‘: frame3[‘Ohio‘][:-1], ‘Nevada‘: frame3[‘Nevada‘][:2]}   # 注意:依次是列标签,行标签
pd.DataFrame(pdata)   # 输出如下:(这里使用:pd.DataFrame(pdata, index=[2001,2000]),不会报错)
    Ohio    Nevada
2000    1.5    NaN
2001    1.7    2.4

下面列出了DataFrame构造函数所能接受的各种数据(表5-1):

如果设置了DataFrame的index和columns的name属性,则这些信息也会被显示出来:
frame3.index.name = ‘year‘; frame3.columns.name = ‘state‘
frame3    # 输出如下:
state    Nevada   Ohio
year
2000    NaN    1.5
2001    2.4      1.7
2002    2.9      3.6

跟Series?样,values属性也会以?维ndarray的形式返回DataFrame中的数据:
frame3.values     # 输出如下:
array([[nan, 1.5],
   [2.4, 1.7],
      [2.9, 3.6]])

如果DataFrame各列的数据类型不同,则值数组的dtype就会选?能兼容所有列的数据类型:
frame2.values     # 输出如下:
array([[2000, ‘Ohio‘, 1.5, nan],
  [2001, ‘Ohio‘, 1.7, -1.2],
  [2002, ‘Ohio‘, 3.6, nan],
  [2001, ‘Nevada‘, 2.4, -1.5],
  [2002, ‘Nevada‘, 2.9, -1.7],
  [2003, ‘Nevada‘, 3.2, nan]], dtype=object)

1、索引对象
pandas的索引对象负责管理轴标签和其他元数据(?如轴名称等)。构建Series或DataFrame时,所?到的任何数组或其他序列的标签都会被转换成?个Index:
obj = pd.Series(range(3), index=[‘a‘, ‘b‘, ‘c‘])
index = obj.index     # 将obj的索引赋值给另一个变量
index       # 输出:Index([‘a‘, ‘b‘, ‘c‘], dtype=‘object‘)
index[1:]         # 输出:Index([‘b‘, ‘c‘], dtype=‘object‘)

Index对象是不可变的,因此?户不能对其进?修改:
index[1] = ‘d‘   # 提示错误:TypeError: Index does not support mutable operations
不可变可以使Index对象在多个数据结构之间安全共享:
labels = pd.Index(np.arange(3))    # 创建一个索引
labels      # 输出:Int64Index([0, 1, 2], dtype=‘int64‘)
obj2 = pd.Series([1.5, -2.5, 0], index=labels)   # 创建对象时指定索引
obj2      # 输出可以看出索引是创建时指定的索引
0    1.5
1    -2.5
2    0.0
dtype: float64
obj2.index is labels   # 输出:True(验证是否是同一个索引)
虽然Index功能不经常使用,但一些操作会生成包含索引化的数据,理解它的工作原理很重要。

除了类似于数组,Index的功能也类似?个固定??的集合:
frame3    # 先看下面前的frame3的输出:
state    Nevada   Ohio
year
2000    NaN    1.5
2001    2.4       1.7
2002    2.9       3.6
‘Ohio‘ in frame3.columns   # 输出:True(判断是否在列索引)
2003 in frame3.index        # 输出:False(判断是否在行索引)

与python的集合不同,pandas的Index可以包含重复的标签:
dup_labels = pd.Index([‘foo‘, ‘foo‘, ‘bar‘, ‘bar‘])   # 包含重复索引
dup_labels   # 输出:Index([‘foo‘, ‘foo‘, ‘bar‘, ‘bar‘], dtype=‘object‘)
选择重复的标签,会显示所有的结果。
每个索引都有?些?法和属性,它们可?于设置逻辑并回答有关该索引所包含的数据的常?问题。下面列出了Index的方法和属性(表5-2)

二、基本功能
下面介绍操作Series和DataFrame中的数据的基本?段。

1、重新索引(reindex)
pandas对象的?个重要?法是reindex,其作?是创建?个新对象,它的数据符合新的索引。例:
obj = pd.Series([4.5, 7.2, -5.3, 3.6], index=[‘d‘, ‘b‘,‘a‘, ‘c‘])
obj   # 输出:
d    4.5
b    7.2
a    -5.3
c    3.6
dtype: float64
?该Series的reindex将会根据新索引进?重排。如果某个索引值当前不存在,就引?缺失值:
obj2 = obj.reindex([‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘])   # 重建索引
obj2     # 输出:
a    -5.3
b    7.2
c    3.6
d    4.5
e    NaN
dtype: float64

对于时间序列这样的有序数据,重新索引时可能需要做?些插值处理。method选项即可达到此?的,例如,使?ffill可以实现前向值填充:
obj3 = pd.Series([‘blue‘, ‘purple‘, ‘yellow‘], index=[0, 2, 4])
obj3      # 输出:
0    blue
2    purple
4    yellow
dtype: object
obj3.reindex(range(6), method=‘ffill‘)   # 输出如下
0    blue
1    blue
2    purple
3    purple
4    yellow
5    yellow
dtype: object
借助DataFrame,reindex可以修改(?和列)索引。只传递?个序列时,会重新索引结果的?:
frame = pd.DataFrame(np.arange(9).reshape((3, 3)),
          index=[‘a‘, ‘c‘, ‘d‘],
          columns=[‘Ohio‘, ‘Texas‘, ‘California‘])
frame    # 输出:
  Ohio    Texas   California
a    0    1    2
c    3    4    5
d    6    7    8
frame2 = frame.reindex([‘a‘, ‘b‘, ‘c‘, ‘d‘])   # 只传递一个序列,修改行索引
frame2      # 输出
     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
列可以?columns关键字重新索引:

states = [‘Texas‘, ‘Utah‘, ‘California‘]
frame.reindex(columns=states)    # 指定columns关键字,修改列索引
  Texas   Utah     California
a    1    NaN    2
c    4    NaN    5
d    7    NaN    8

下面列出了reindex函数的各参数及说明(表5-3)

2、丢弃指定轴上的项
丢弃某条轴上的?个或多个项很简单,只要有?个索引数组或列表即可。由于需要执??些数据整理和集合逻辑,所以drop?法返回的是?个在指定轴上删除了指定值的新对象:
obj = pd.Series(np.arange(5.), index=[‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘])   # 假设有这个Series序列
obj      # 输出如下
a    0.0
b    1.0
c    2.0
d    3.0
e    4.0
dtype: float64
new_obj = obj.drop(‘c‘)   # 删除传入的值,并得到新的Index
new_obj
a    0.0
b    1.0
d    3.0
e    4.0
dtype: float64
obj.drop([‘d‘, ‘c‘])      # 删除传入的值,注意参数是列表
a    0.0
b    1.0
e    4.0
dtype: float64

对于DataFrame,可以删除任意轴上的索引值。先新建?个DataFrame例?:
data = pd.DataFrame(np.arange(16).reshape((4, 4)),
          index=[‘Ohio‘, ‘Colorado‘, ‘Utah‘, ‘New York‘],
          columns=[‘one‘, ‘two‘, ‘three‘, ‘four‘])
data    # 输出如下:
    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
?标签序列调?drop会从?标签(axis 0)删除值:
data.drop([‘Colorado‘, ‘Ohio‘])    # 输出如下:
    one   two   three   four
Utah    8    9    10    11
New York 12   13    14    15
通过传递axis=1或axis=‘columns‘可以删除列的值:
data.drop(‘two‘, axis=1)    # 输出如下:
    one  three    four
Ohio    0    2      3
Colorado  4    6      7
Utah    8   10    11
New York 12    14    15
data.drop([‘two‘, ‘four‘], axis=‘columns‘)   # 输出如下:
    one     three
Ohio    0    2
Colorado  4    6
Utah    8    10
New York 12   14

许多函数,如drop,会修改Series或DataFrame的??或形状,可就地修改对象,不会返回新的对象:
obj.drop(‘c‘, inplace=True)   # ??使?inplace,它会销毁所有被删除的数据。
obj    # 输出如下:
a    0.0
b    1.0
d    3.0
e    4.0
dtype: float64

3、索引、选取和过滤
Series索引(obj[...])的?作?式类似于NumPy数组的索引,只不过Series的索引值不只是整数。例如:
obj = pd.Series(np.arange(4.), index=[‘a‘, ‘b‘, ‘c‘, ‘d‘])
obj   # 输出如下:
a    0.0
b    1.0
c    2.0
d    3.0
dtype: float64
obj[‘b‘]      # 输出:1.0
obj[1]       # 输出:1.0
obj[2:4]    # 输出如下:
c    2.0
d    3.0
dtype: float64
obj[[‘b‘, ‘a‘, ‘d‘]]   # 输出如下:
b    1.0
a    0.0
d    3.0
dtype: float64
obj[[1, 3]]      # 输出如下:(参数是列表)
b    1.0
d    3.0
dtype: float64
obj[obj < 2]    # 输出如下:(按条件索引,布尔索引)
a    0.0
b    1.0
dtype: float64
利?标签的切?运算与普通的Python切?运算不同,其末端是包含的:
obj[‘b‘:‘c‘]    # 输出如下:
b   1.0
c    2.0
dtype: float64
?切?可以对Series的相应部分进?设置:
obj[‘b‘:‘c‘] = 5
obj    # 输出如下:
a    0.0
b    5.0
c    5.0
d    3.0
dtype: float64

??个值或序列对DataFrame进?索引其实就是获取?个或多个列:
data = pd.DataFrame(np.arange(16).reshape((4, 4)),
          index=[‘Ohio‘, ‘Colorado‘, ‘Utah‘, ‘New York‘],
          columns=[‘one‘, ‘two‘, ‘three‘, ‘four‘])
data    # 输出如下:
    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
data[‘two‘]   # 输出如下
Ohio    1
Colorado  5
Utah    9
New York 13
Name: two, dtype: int32
data[[‘three‘, ‘one‘]]   # 输出如下:
    three   one
Ohio      2    0
Colorado    6    4
Utah    10    8
New York 14    12
data[:2]    # 输出如下:(选取前2行)
    one   two   three    four
Ohio    0    1    2    3
Colorado  4    5    6    7
data[data[‘three‘] > 5]   # 输出如下:(选取满足条件的行)
    one   two    three       four
Colorado  4    5    6      7
Utah    8    9   10    11
New York 12    13   14    15
选取?的语法data[:2]?分?便。向[ ]传递单?的元素或列表,就可选择列。

另?种?法是通过布尔型DataFrame进?索引:?如下?这个由标量?较运算得出的
data < 5    # 输出如下:
        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[data < 5] = 0   # 输出如下:(改变满足条件的值)
data
    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
这使得DataFrame的语法与NumPy?维数组的语法很像。

4、?loc和iloc进?选取

DataFrame?标签索引,引?特殊的标签运算符loc和iloc。它们可以像?类似NumPy的标记,使?轴标签(loc)或整数索引(iloc),从DataFrame选择?和列的?集。先看?个初步示例,通过标签选择??和多列:
data.loc[‘Colorado‘, [‘two‘, ‘three‘]]   # 选取‘Colorado‘行,和 [‘two‘, ‘three‘]列,输出如下:
two      5
three    6
Name: Colorado, dtype: int32
然后?iloc和整数进?选取:
data.iloc[2, [3, 0, 1]]    # 输出如下:
four    11
one    8
two    9
Name: Utah, dtype: int32
data.iloc[2]   # 输出如下:(选取第三行数据)
one    8
two    9
three   10
four    11
Name: Utah, dtype: int32
data.iloc[[1, 2], [3, 0, 1]]   # 输出如下:(选取多行和多列)
      four    one    two
Colorado      7    0    5
Utah      11    8    9

这两个索引函数也适?于?个标签或多个标签的切?:
data.loc[:‘Utah‘, ‘two‘]     # 输出如下:
Ohio    0
Colorado  5
Utah    9
Name: two, dtype: int32
data.iloc[:, :3][data.three > 5]   # 输出如下:(选取满足多种条件的数据)
      one    two    three
Colorado      0    5    6
Utah         8    9    10
New York    12    13    14
在pandas中,有多个?法可以选取和重新组合数据。当然还有更多的方法进行层级化索引。

DataFrame的索引选项如下所示(表5-4):

5、整数索引
pandas整数索引与Python内置的列表和元组的索引语法不同。
例如,你可能不认为下?的代码会出错:
ser = pd.Series(np.arange(3.))
ser   # 输出如下:
0   0.0
1   1.0
2   2.0
dtype: float64
ser[-1]   # 索引会报错,KeyError: -1,因为轴索引含有整数
ser有包含0,1,2的索引,但是引??户想要的东?(基于标签或位置的索引)很难:

另外,对于?整数索引,不会产?歧义:
ser2 = pd.Series(np.arange(3.), index=[‘a‘, ‘b‘, ‘c‘])
ser2[-1]    # 输出:2.0
为了进?统?,如果轴索引含有整数,数据选取总会使?标签。为了更准确,请使?loc(标签)或iloc(整数):
ser[:1]   # 整数索引,注意看与下面2个索引的区别,输出如下:
0    0.0
dtype: float64
ser.loc[:1]    # 标签索引,输出如下:
0    0.0
1    1.0
dtype: float64
ser.iloc[:1]    # 整数索引,输出如下:
0    0.0
dtype: float64

6、算术运算和数据对?
pandas最重要的?个功能是,它可以对不同索引的对象进?算术运算。在将对象相加时,如果存在不同的索引对,则结果的索引就是该索引对的并集。对于有数据库经验的话,这就像在索引标签上进??动外连接。看?个简单的例?:
s1 = pd.Series([7.3, -2.5, 3.4, 1.5], index=[‘a‘, ‘c‘, ‘d‘, ‘e‘])
s2 = pd.Series([-2.1, 3.6, -1.5, 4, 3.1],
        index=[‘a‘, ‘c‘, ‘e‘, ‘f‘, ‘g‘])
s1    # 输出如下:
a    7.3
c    -2.5
d    3.4
e    1.5
dtype: float64
s2    # 输出如下:
a    -2.1
c    3.6
e    -1.5
f    4.0
g    3.1
dtype: float64
s1 + s2    # 输出如下:
a    5.2
c    1.1
d    NaN
e    0.0
f    NaN
g    NaN
dtype: float64
?动的数据对?操作在不重叠的索引处引?了NA值。缺失值会在算术运算过程中传播。

对于DataFrame,对?操作会同时发?在?和列上:
df1 = pd.DataFrame(np.arange(9.).reshape((3, 3)), columns=list(‘bcd‘), index=[‘Ohio‘, ‘Texas‘, ‘Colorado‘])
df2 = pd.DataFrame(np.arange(12.).reshape((4, 3)), columns=list(‘bde‘), index=[‘Utah‘, ‘Ohio‘, ‘Texas‘, ‘Oregon‘])
df1    # 输出如下:
      b     c       d
Ohio      0.0    1.0    2.0
Texas    3.0    4.0    5.0
Colorado    6.0    7.0    8.0
df2    # 输出如下:
         b       d       e
Utah         0.0    1.0    2.0
Ohio         3.0    4.0    5.0
Texas       6.0    7.0    8.0
Oregon    9.0    10.0   11.0

把它们相加后将会返回?个新的DataFrame,其索引和列为原来那两个DataFrame的并集:
df1 + df2    # 输出如下:
        b        c        d      e
Colorado    NaN    NaN   NaN    NaN
Ohio      3.0      NaN    6.0     NaN
Oregon      NaN    NaN    NaN    NaN
Texas     9.0    NaN    12.0    NaN
Utah     NaN    NaN    NaN    NaN
因为‘c‘和‘e‘列均不在两个DataFrame对象中,在结果中以缺省值呈现。?也是同样。

如果DataFrame对象相加,没有共?的列或?标签,结果都会是空
df1 = pd.DataFrame({‘A‘: [1, 2]})
df2 = pd.DataFrame({‘B‘: [3, 4]})
df1    # 输出如下:
      A
0    1
1    2
df2    # 输出如下:
      B
0    3
1    4
df1 - df2    # 输出如下:(没有共?的列或?标签,结果都会是空)
    A     B
0   NaN   NaN
1   NaN   NaN

7、在算术?法中填充值
在对不同索引的对象进?算术运算时,你可能希望当?个对象中某个轴标签在另?个对象中找不到时填充?个特殊值(?如0):
df1 = pd.DataFrame(np.arange(12.).reshape((3, 4)), columns=list(‘abcd‘))
df2 = pd.DataFrame(np.arange(20.).reshape((4, 5)), columns=list(‘abcde‘))
df2.loc[1, ‘b‘] = np.nan
df1    # 输出如下:
    a       b      c       d
0    0.0    1.0      2.0    3.0
1    4.0    5.0      6.0    7.0
2    8.0    9.0    10.0    11.0
df2    # 输出如下:
      a       b       c      d       e
0      0.0    1.0       2.0      3.0    4.0
1      5.0    NaN    7.0       8.0    9.0
2    10.0    11.0    12.0    13.0    14.0
3    15.0    16.0    17.0    18.0    19.0
将它们相加时,没有重叠的位置就会产?NA值:
df1 + df2    # 输出如下:
    a      b       c      d       e
0    0.0        2.0    4.0        6.0    NaN
1    9.0      NaN    13.0    15.0    NaN
2    18.0    20.0    22.0     24.0    NaN
3    NaN    NaN    NaN    NaN    NaN
使?df1的add?法,传?df2以及?个fill_value参数:
df1.add(df2, fill_value=0)   # 输出如下:(参数fill_value指定缺失的话用替代)
      a       b          c       d         e
0      0.0    2.0        4.0    6.0      4.0
1      9.0    5.0      13.0    15.0    9.0
2    18.0    20.0    22.0    24.0    14.0
3    15.0    16.0    17.0    18.0    19.0

下面列出了Series和DataFrame的算术?法。它们每个都有?个副本,以字?r开头,
它会翻转参数。因此这两个语句是等价的:
1 / df1    # 输出如下:
        a        b            c            d
0        inf  1.000000    0.500000    0.333333
1    0.250000     0.200000    0.166667    0.142857
2    0.125000     0.111111      0.100000    0.090909
df1.rdiv(1)    # 输出如下:
        a        b            c            d
0        inf  1.000000    0.500000    0.333333
1    0.250000     0.200000    0.166667    0.142857
2    0.125000     0.111111      0.100000    0.090909

灵活的算术?法(Series和DataFrame的算术?法)(表5-5):

与此类似,在对Series或DataFrame重新索引时,也可以指定?个填充值:
df1.reindex(columns=df2.columns, fill_value=0)     # 输出如下:
    a     b      c       d    e
0    0.0    1.0    2.0    3.0    0
1    4.0    5.0    6.0    7.0    0
2    8.0    9.0     10.0     11.0    0

8、DataFrame和Series之间的运算

DataFrame和Series之间算术运算也是有明确规定的。先来看?个例?,计算?个?维数组与其某?之间的差:
arr = np.arange(12.).reshape((3, 4))
arr    # 输出如下:
array([[ 0., 1., 2., 3.],
  [ 4., 5., 6., 7.],
  [ 8., 9., 10., 11.]])
arr[0]      # 输出:array([0., 1., 2., 3.])
arr - arr[0]    # 输出如下:
array([[0., 0., 0., 0.],
  [4., 4., 4., 4.],
  [8., 8., 8., 8.]])
当从arr减去arr[0],每??都会执?这个操作。这就叫做?播(broadcasting)。DataFrame和Series之间的运算差不多也是如此:
frame = pd.DataFrame(np.arange(12.).reshape((4, 3)), columns=list(‘bde‘), index=[‘Utah‘, ‘Ohio‘, ‘Texas‘, ‘Oregon‘])
series = frame.iloc[0]
frame   # 输出如下:
      b      d     e
Utah     0.0    1.0    2.0
Ohio     3.0    4.0    5.0
Texas   6.0    7.0    8.0
Oregon   9.0    10.0   11.0
series    # 输出如下:
b    0.0
d    1.0
e    2.0
Name: Utah, dtype: float64
默认情况下,DataFrame和Series之间的算术运算会将Series的索引匹配到DataFrame的列,然后沿着??直向下?播:
frame - series   # 输出如下:
       b       d       e
Utah    0.0    0.0    0.0
Ohio    3.0    3.0    3.0
Texas     6.0    6.0    6.0
Oregon  9.0    9.0    9.0

如果某个索引值在DataFrame的列或Series的索引中找不到,则参与运算的两个对象就会被重新索引以形成并集:
series2 = pd.Series(range(3), index=[‘b‘, ‘e‘, ‘f‘])
frame + series2   # 输出如下:
      b      d       e       f
Utah    0.0   NaN    3.0    NaN
Ohio    3.0   NaN    6.0    NaN
Texas     6.0   NaN    9.0    NaN
Oregon  9.0   NaN    12.0   NaN

如果你希望匹配?且在列上?播,则必须使?算术运算?法。例如:
frame    # 输出如下:
         b       d       e
Utah    0.0    1.0    2.0
Ohio    3.0    4.0    5.0
Texas     6.0    7.0    8.0
Oregon   9.0   10.0   11.0
series3    # 输出如下:
Utah    1.0
Ohio    4.0
Texas   7.0
Oregon  10.0
Name: d, dtype: float64
frame.sub(series3, axis=‘index‘)    # 输出如下:
         b     d       e
Utah        -1.0    0.0    1.0
Ohio        -1.0    0.0    1.0
Texas      -1.0    0.0    1.0
Oregon   -1.0    0.0    1.0
传?的轴号就是希望匹配的轴。在本例中,我们的?的是匹配DataFrame的?索引(axis=‘index‘ or axis=0)并进??播。

9、函数应?和映射
NumPy的ufuncs(元素级数组?法)也可?于操作pandas对象:
frame = pd.DataFrame(np.random.randn(4, 3), columns=list(‘bde‘), index=[‘Utah‘, ‘Ohio‘, ‘Texas‘, ‘Oregon‘])
frame    # 输出如下:
          b        d          e
Utah    -0.238758   -1.228157   -0.433499
Ohio    0.281959    0.229944    1.908042
Texas   -1.180401   -0.234310   -0.264257
Oregon  0.635323   -1.248893    1.319811
np.abs(frame)   # 输出如下:
        b        d       e
Utah    0.238758    1.228157    0.433499
Ohio    0.281959    0.229944    1.908042
Texas     1.180401    0.234310    0.264257
Oregon     0.635323    1.248893    1.319811

另?个常?的操作是,将函数应?到由各列或?所形成的?维数组上。DataFrame的apply?法即可实现此功能:
f = lambda x: x.max() - x.min()
frame.apply(f)   # 输出如下:
b    1.815723
d    1.478837
e    2.341541
dtype: float64
这?的函数f,计算了?个Series的最?和虽?的差,在frane的每列都执?了?次。结果是?个Series,使?frame的列作为索引。

如果传递axis=‘columns‘到apply,这个函数会在每?执?:
frame.apply(f, axis=‘columns‘)   # 输出如下:
Utah    0.989399
Ohio    1.678098
Texas   0.946090
Oregon   2.568704
dtype: float64
许多常?的数组统计功能都被实现成DataFrame的?法(如sum和mean),因此?需使?apply?法。传递到apply的函数不是必须返回?个标量,还可以返回由多个值组成的Series:
def f(x):
  return pd.Series([x.min(), x.max()], index=[‘min‘, ‘max‘])
frame.apply(f)    # 输出如下:
        b         d         e
min   -1.180401   -1.248893   -0.433499
max      0.635323    0.229944    1.908042

元素级的Python函数也是可以?的。假如你想得到frame中各个浮点值的格式化字符串,使?applymap即可:
format = lambda x: ‘%.2f‘ % x
frame.applymap(format)   # 输出如下:
      b      d     e
Utah    -0.24    -1.23   -0.43
Ohio    0.28    0.23      1.91
Texas   -1.18    -0.23    -0.26
Oregon  0.64    -1.25    1.32
之所以叫做applymap,是因为Series有?个?于应?元素级函数的map?法:
frame[‘e‘].map(format)   # 输出如下:
Utah    -0.43
Ohio    1.91
Texas   -0.26
Oregon   1.32
Name: e, dtype: object

10、排序和排名
根据条件对数据集排序(sorting)也是?种重要的内置运算。要对?或列索引进?排序(按字典顺序),可使?sort_index?法,它将返回?个已排序的新对象:
obj = pd.Series(range(4), index=[‘d‘, ‘a‘, ‘b‘, ‘c‘])
obj.sort_index()    # 输出如下:
a    1
b    2
c    3
d    0
dtype: int64

对于DataFrame,则可以根据任意?个轴上的索引进?排序:
frame = pd.DataFrame(np.arange(8).reshape((2, 4)), index=[‘three‘, ‘one‘], columns=[‘d‘, ‘a‘, ‘b‘, ‘c‘])
frame.sort_index()    # 输出如下:(行索引排序)
       d    a    b    c
one      4    5    6    7
three    0    1   2    3
frame.sort_index(axis=1)   # 输出如下:(指定参数axis=1按列标签排序)
       a    b    c    d
three    1    2    3    0
one      5    6    7    4
数据默认是按升序排序的,但也可以降序排序:
frame.sort_index(axis=1, ascending=False)   # 输出如下:(列标签降序排序)
       d    c    b    a
three    0    3    2   1
one      4    7   6    5

若要按值对Series进?排序,可使?其sort_values?法:
obj = pd.Series([4, 7, -3, 2])
obj.sort_values()     # 输出如下:
2    -3
3    2
0    4
1    7
dtype: int64
在排序时,任何缺失值默认都会被放到Series的末尾:
obj = pd.Series([4, np.nan, 7, np.nan, -3, 2])
obj.sort_values()   # 输出如下:
4    -3.0
5    2.0
0    4.0
2    7.0
1    NaN
3    NaN
dtype: float64

当排序?个DataFrame时,你可能希望根据?个或多个列中的值进?排序。将?个或多个列的名字传递给sort_values的by选项即可达到该?的:
frame = pd.DataFrame({‘b‘: [4, 7, -3, 2], ‘a‘: [0, 1, 0, 1]})
frame.sort_values(by=‘b‘)   # 输出如下:(对b列排序)
      b    a
2   -3    0
3    2    1
0    4    0
1    7    1
要根据多个列进?排序,传?名称的列表即可:
frame.sort_values(by=[‘a‘, ‘b‘])   # 输出如下:(参数是列表)
      b    a
2   -3    0
0    4    0
3    2    1
1    7    1

排名会从1开始?直到数组中有效数据的数量。接下来介绍Series和DataFrame的rank?法。
默认情况下,rank是通过“为各组分配?个平均排名”的?式破坏平级关系的:
obj = pd.Series([7, -5, 7, 4, 2, 0, 4])
obj.rank()    # 输出如下:
0    6.5
1    1.0
2    6.5
3    4.5
4    3.0
5    2.0
6    4.5
dtype: float64
也可以根据值在原数据中出现的顺序给出排名:
obj.rank(method=‘first‘)   # 输出如下:
0    6.0
1    1.0
2    7.0
3    4.0
4    3.0
5   2.0
6   5.0
dtype: float64
这?,条?0和2没有使?平均排名6.5,它们被设成了6和7,因为数据中标签0位于标签2的前?。
也可以按降序进?排名:
obj.rank(ascending=False, method=‘max‘)   # 输出如下:
0    2.0
1    7.0
2    2.0
3    4.0
4    5.0
5    6.0
6    4.0
dtype: float64

DataFrame可以在?或列上计算排名:
frame = pd.DataFrame({‘b‘: [4.3, 7, -3, 2], ‘a‘: [0, 1, 0, 1], ‘c‘: [-2, 5, 8, -2.5]})

frame    # 输出如下:
    b    a       c
0    4.3    0   -2.0
1    7.0    1    5.0
2   -3.0    0    8.0
3    2.0    1   -2.5
frame.rank(axis=‘columns‘)   # 输出如下:
    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

下面是所有?于破坏平级关系的method选项(排名时?于破坏平级关系的?法)(表5-6)

(未完待续)

原文地址:https://www.cnblogs.com/Micro0623/p/10089908.html

时间: 2024-10-14 10:38:51

第五篇 pandas??的相关文章

秒杀多线程第十五篇 关键段,事件,互斥量,信号量的“遗弃”问题

版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 秒杀多线程第十五篇 关键段,事件,互斥量,信号量的“遗弃”问题 在<秒杀多线程第九篇 经典线程同步总结 关键段 事件 互斥量 信号量>中对经典多线程同步互斥问题进行了回顾和总结,这篇文章对Windows系统下常用的线程同步互斥机制——关键段.事件.互斥量.信号量进行了总结.有网友问到互斥量能处理“遗弃”问题,事件和信号量是否也能处理“遗弃”问题.因此本文将对事件和信号量作个试验,看看事件和信号量能否处理“遗弃”问题. 一.

前端工程师技能之photoshop巧用系列第五篇——雪碧图

显示目录 目录 [1]定义 [2]应用场景 [3]合并[4]实现[5]维护 前面的话 前面已经介绍过,描述性图片最终要合并为雪碧图.本文是photoshop巧用系列第五篇--雪碧图 定义 css雪碧图(sprite)是一种网页图片应用处理方式,它允许将一个页面涉及到的所有零星图片都包含到一张大图中.使用雪碧图的处理方式可以实现两个优点: [1]减少http请求次数 [2]减少图片大小,提升网页加载速度 (多张图片加载速度小于拼合成的图片的加载速度) 凡事都不完美,实现优点的同时也带来了缺点,即提

Python之路【第十五篇】:Web框架

Python之路[第十五篇]:Web框架 Web框架本质 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #!/usr/bin/env python #coding:utf-8   import socket   def handle_request(client):     buf = client.recv(10

【Python五篇慢慢弹(5)】‘类’过依然继续前行,直至ending再出发

‘类’过依然继续前行,直至ending再出发 作者:白宁超 2016年10月10日22:36:57 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给出的pythondoc入门资料包含了基本要点.本文是对文档常用核心要点进行梳理,简单冗余知识不再介绍,作者假使你用c/java/c#/c++任一种语言基础.本系列文章属于入门内容,老鸟可以略看也可以略过,新鸟可以从篇一<快速上手学python>先接触下python怎样安装与运行,以及pychar

第十五篇 Integration Services:SSIS参数

本篇文章是Integration Services系列的第十五篇,详细内容请参考原文. 简介在前一篇,我们使用SSDT-BI将第一个SSIS项目My_First_SSIS_Project升级/转换到SSIS 2012.在这一篇,我们将探讨SSIS变量的姊妹:SSIS参数.我们将展示参数配置,通过包参数管理动态属性值,以及在SSIS包执行期间参数是如何配置和使用的.首先在SSDT-BI打开转换过的My_First_SSIS_Project,如图15.1所示:图15.1My_First_SSIS_P

《你的灯亮着吗》第五篇、第六篇总结

第五篇讲的是问题是从哪儿来的?由一个叫珍妮特去波兰拜访她的祖母在旅途中遇到的麻烦引出主题.一开始她把问题推到“官僚主义”上,她感觉这似乎是最恰当的.但是最后她发现她十分倾向于把整件事归咎于“官僚主义”,之后她提出了一个至关重要的问题:问题是从哪儿来的?从这点出发,她成功找到乐各种备选答案.后来,珍妮特想这个问题的根源也许是她自己.她开始以正常的心态面对曾被她称作灰脸先生的人,他们顺利的交谈,最后事情的到了解决.一切都正常的进行着,一旦你确定问题真正从哪来,尤其是因为问题的根源常常在你自己身上.

认识元数据和IL(下)&lt;第五篇&gt;

书接上回: 第二十四回:认识元数据和IL(上) , 第二十五回:认识元数据和IL(中) 我们继续. 终于到了,说说元数据和IL在JIT编译时的角色了,虽然两个回合的铺垫未免铺张,但是却丝毫不为过,因为只有充分的认知才有足够的体会,技术也是如此.那么,我们就开始沿着方法调用的轨迹,追随元数据和IL在那个神秘瞬间所贡献的力量吧 5 元数据和IL在JIT编译时 CLR最终执行的只有本地机器码,所以JIT编译的作用是在运行时将IL代码解析为机器码执行.对于JIT编译,我们会以专门的篇幅来全面了解,本文只

第五篇 Getting Started with ORACLE EBS(开始学习ORACLE EBS)

第一篇介绍了ERP软件是供应链管理软件.告诉你这个软件改善或提升企业管理的切入点和着力点.有了着力点才能给力. 第二篇介绍了什么是咨询以及咨询工作共通的章法,告诉了你咨询的套路是什么,就像练习一套拳,套路就是这样的,这些是形式的东西. 第三篇介绍了EXCEL和基于数据库的软件在数据处理方面的异同. 第四篇介绍了在国内做咨询你应该具备的一些基础理论常识. 从本篇也就是第五篇开始着手介绍一些循序渐进学习ORACLE EBS的知识.面向的读者是ORACLE EBS系统实施新手.并欢迎高手不吝批评纠正.

【Python之旅】第五篇(二):Python Socket单线程+阻塞模式

前面第五篇(一)中的一个Socket例子其实就是单线程的,即Server端一次只能接受来自一个Client端的连接,为了更好的说明socket单线程和阻塞模式,下面对前面的例子做修改. 1.单线程+阻塞+交互式 前面的例子是单线程阻塞和非交互式的,现在改写为交互式的,即不会执行一次就结束,希望达到的效果是,发送的数据由User输入,然后Server端进行接收. Server端:与上个例子一样,并没有什么变化 import socket                #导入socket类   HO