pandas 学习

Pandas处理以下三个数据结构 ,这些数据结构构建在Numpy数组之上,这意味着它们很快。

  • 系列(Series)
  • 数据帧(DataFrame)
  • 面板(Panel)

较高维数据结构是其较低维数据结构的容器。 DataFrameSeries的容器,PanelDataFrame的容器。

数据结构 维数 描述
系列(Series) 1 一维数组。均匀数据,大小不变,值可变
数据帧(DataFrame) 2 二维数组。异构数据,大小可变,值可变
面板(Panel) 3 三维数组。异构数据,大小可变,值可变

导入模块

import pandas as pd
import numpy as np

Series 操作

系列(Series)是能够保存任何类型的数据(整数,字符串,浮点数,Python对象等)的一维标记数组。轴标签统称为索引。

创建Pandas系列

pandas.Series( data, index, dtype, copy)

构造函数的参数如下

参数 描述
data 数据,如:ndarraylistconstants
index 索引值必须是唯一的和散列的,与数据的长度相同。 默认np.arange(n)
dtype dtype用于数据类型。如果没有,将推断数据类型
copy 复制数据,默认为false

使用各种输入创建一个系列:

  • 数组
  • 字典
  • 标量值或常数

创建一个空的系列

s = pd.Series()
Series([], dtype: float64)

从ndarray创建一个系列

传递的索引必须具有相同的长度。不传递索引,默认的索引将是 ndarray 长度。

data = np.array(['a','b','c','d'])
s = pd.Series(data)
s = pd.Series(data,index=[100,101,102,103])
0   a
1   b
2   c
3   d

100  a
101  b
102  c
103  d

从字典创建一个系列

不指定索引,则按排序顺序:字典key == 索引。

指定索引,索引中与字典key相同的索引,字典value为值;没有的字典key索引值,索引顺序保持不变,缺少的元素使用NaN(不是数字)填充

data = {'a' : 0., 'b' : 1., 'c' : 2.}
s = pd.Series(data)
s = pd.Series(data,index=['b','c','d','a'])
a 0.0
b 1.0
c 2.0

b 1.0
c 2.0
d NaN
a 0.0

从标量创建一个系列

必须提供索引。将重复该值以匹配索引的长度。

s = pd.Series(5, index=[0, 1, 2, 3])
0  5
1  5
2  5
3  5

查看 Series 数据

s[0]  # 根据索引
s[:3]  # 根据索引切片
s[-3:]
s['a']  # 根据字典key的索引名称
s[['a','c','d']]  # 根据多个索引名称的列表
s[[1,2,3]]  # 根据多个索引的列表
c  3
d  4
e  5

查看不包含标签,则会出现异常

print s['f']
KeyError: 'f'

DataFrame 操作

创建数据帧DataFrame

通过传递numpy数组,使用datetime索引和标记列来创建DataFrame

dates = pd.date_range('20170101', periods=7)
df = pd.DataFrame(np.random.randn(7,4), index=dates, columns=list('ABCD'))
DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04',
               '2017-01-05', '2017-01-06', '2017-01-07'],
              dtype='datetime64[ns]', freq='D')
--------------------------------
                   A         B         C         D
2017-01-01 -0.732038  0.329773 -0.156383  0.270800
2017-01-02  0.750144  0.722037 -0.849848 -1.105319
2017-01-03 -0.786664 -0.204211  1.246395  0.292975
2017-01-04 -1.108991  2.228375  0.079700 -1.738507
2017-01-05  0.348526 -0.960212  0.190978 -2.223966
2017-01-06 -0.579689 -1.355910  0.095982  1.233833
2017-01-07  1.086872  0.664982  0.377787  1.012772

通过传递字典来创建DataFrame。参考以下示例代码 -

df2 = pd.DataFrame({ 'A' : 1.,
                     'B' : pd.Timestamp('20170102'),
                     'C' : pd.Series(1,index=list(range(4)),dtype='float32'),
                     'D' : np.array([3] * 4,dtype='int32'),
                     'E' : pd.Categorical(["test","train","test","train"]),
                     'F' : 'foo' })
     A          B    C  D      E    F
0  1.0 2017-01-02  1.0  3   test  foo
1  1.0 2017-01-02  1.0  3  train  foo
2  1.0 2017-01-02  1.0  3   test  foo
3  1.0 2017-01-02  1.0  3  train  foo

pandas报错:ValueError: If using all scalar values, you must pass an index

字典转为DataFrame,字典中的value至少有一个有索引,长度才可以,所有值都没有索引,无法确定长度而报错。

查看数据

查看开头,结尾数据

df.head()   # 前几行数据,不输入有默认行数为5
df.tail(3)  # 前3行数据
                   A         B         C         D
2017-01-01 -0.520856 -0.555019 -2.286424  1.745681
2017-01-02  1.114030  0.861933  0.795958  0.420670
2017-01-03 -0.343605 -0.937356  0.052693 -0.540735
2017-01-04  1.587684 -0.743756  0.021738 -0.702190
2017-01-05  1.243403  0.930299  0.234343  1.604182
------------------------------------------------------------
                   A         B         C         D
2017-01-05  1.243403  0.930299  0.234343  1.604182
2017-01-06 -0.087004 -0.368055  1.434022  0.464193
2017-01-07 -1.248981  0.973724 -0.288384 -0.577388

查看索引,列和底层numpy数据(行,列,值)

df.index     # 查看行索引
df.columns   # 查看列字段
df.values    # 查看数据
DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04',
               '2017-01-05', '2017-01-06', '2017-01-07'],
              dtype='datetime64[ns]', freq='D')

Index(['A', 'B', 'C', 'D'], dtype='object')

[[ 2.23820398  0.18440123  0.08039084 -0.27751926]
 [-0.12335513  0.36641304 -0.28617579  0.34383109]
 [-0.85403491  0.63876989  1.26032173 -1.27382333]
 [-0.07262661 -0.01788962  0.28748668  1.12715561]
 [-1.14293392 -0.88263364  0.72250762 -1.64051326]
 [ 0.41864083  0.40545953 -0.14591541 -0.57168728]
 [ 1.01383531 -0.22793823 -0.44045634  1.04799829]]

描述显示数据的快速统计摘要

df.describe()
              A         B         C         D
count  7.000000  7.000000  7.000000  7.000000
mean  -0.675425 -0.257835  0.144049  0.275621
std    1.697957  0.793953  1.301520  1.412291
min   -2.595040 -1.200401 -1.230538 -0.976166
25%   -1.992393 -0.723464 -0.897041 -0.800919
50%   -1.050666 -0.445612  0.004719 -0.705840
75%    0.592677  0.068574  0.874195  1.398337
max    1.717166  1.150948  2.279856  2.416514

转置数据

df.T
   2017-01-01  2017-01-02  2017-01-03  2017-01-04  2017-01-05  2017-01-06
A    0.932454   -2.148503    1.398975    1.565676   -0.167527   -0.242041
B    0.584585    1.373330   -0.069801   -0.102857    1.286432   -0.703491
C   -0.345119   -0.680955    1.686750    1.184996    0.016170   -0.663963
D    0.431751    0.444830   -1.524739    0.040007    0.220172    1.423627

通过轴排序

df.sort_index(axis=1, ascending=False)  # 横轴,ascending=False 从大到小,降序
df.sort_index(axis=0, ascending=False)  # 纵轴
# 横轴倒序,axis=1
				D         C         B         A
2017-01-01  0.426359  2.542352 -0.324047  0.418973
2017-01-02 -0.834625 -1.356709  0.150744 -1.690500
2017-01-03 -0.018274  0.900801  1.072851  0.149830
2017-01-04 -1.075027 -0.889379 -0.663223 -1.404002
2017-01-05 -1.273966 -1.335761 -1.356561 -1.135199
2017-01-06 -1.590793  0.693430 -0.504164  0.143386

# 纵轴倒序,axis=0
				A			B			C			D
2020-01-07	0.002582	-0.684076	-1.154203	-0.419264
2020-01-06	0.040282	1.085169	0.156559	-0.843088
2020-01-05	2.256867	1.329317	-0.660518	0.357097
2020-01-04	-0.486968	-1.126489	-1.530925	-0.036522
2020-01-03	-0.926477	-0.002553	-0.176788	1.867908
2020-01-02	-1.775777	0.226779	1.918664	2.182794
2020-01-01	-0.250033	0.426570	0.196574	2.200098

按值排序

df.sort_values(by='B')
                   A         B         C         D
2017-01-06  0.764517 -1.526019  0.400456 -0.182082
2017-01-05 -0.177845 -1.269836 -0.534676  0.796666
2017-01-04 -0.981485 -0.082572 -1.272123  0.508929
2017-01-02 -0.290117  0.053005 -0.295628 -0.346965
2017-01-03  0.941131  0.799280  2.054011 -0.684088
2017-01-01  0.597788  0.892008  0.903053 -0.821024

选择区块

选择一列,产生一个系列

df.A
df['A']
2017-01-01    0.317460
2017-01-02   -0.933726
2017-01-03    0.167860
2017-01-04    0.816184
2017-01-05   -0.745503
2017-01-06    0.505319
Freq: D, Name: A, dtype: float64

选择通过[]操作符,选择切片行

df[0:3]  # 通过索引,取左不取右

df['20170102':'20170103']  # 通过索引名称,取左右边界
                   A         B         C         D
2017-01-01  1.103449  0.926571 -1.649978 -0.309270
2017-01-02  0.516404 -0.734076 -0.081163 -0.528497
2017-01-03  0.240356  0.231224 -1.463315 -1.157256

                   A         B         C         D
2017-01-02  0.516404 -0.734076 -0.081163 -0.528497
2017-01-03  0.240356  0.231224 -1.463315 -1.157256

loc 通过索引名称取一行

df.loc[dates[0]]
A   -0.483292
B   -0.536987
C   -0.889947
D    1.250857
Name: 2017-01-01 00:00:00, dtype: float64

loc 通过标签名称选择多行多列,取左右边界

df.loc[:,['A','B']]  # 所有行,AB两列
df.loc['20170102':'20170104',['A','B']]  # 02-04行,AB两列
df.loc['20170102',['A','B']]  # 02一行,AB两列
df.loc[dates[0],'A']  # dates[0]日期名称一行,A一列,即具体的标量值
                   A         B
2017-01-01  0.479048 -0.105106
2017-01-02  0.172920  0.086570
2017-01-03 -1.302485 -0.593550
2017-01-04 -0.595438  1.304054
2017-01-05  0.154267  1.336219
2017-01-06 -0.341204  0.781300

                   A         B
2017-01-02  1.062995 -0.108277
2017-01-03  1.962106 -0.294664
2017-01-04 -0.128576  0.717738

A    0.252749
B    0.119747
Name: 2017-01-02 00:00:00, dtype: float64

-0.0839903627822

at 通过行列名称快速访问标量(等同于先前的方法)

df.at[dates[0],'A']
-0.0839903627822

iloc 通过行列index索引位置取一行

df.iloc[3]
A    0.944506
B    1.035781
C    0.421373
D    0.017660
Name: 2017-01-04 00:00:00, dtype: float64

iloc 通过行列索引index位置切片,取多行多列

df.iloc[3:5,0:2]
df.iloc[1:3,:]
df.iloc[:,1:3]
df.iloc[1,1]  # 取第一行第一列,得到标量值
                   A         B
2017-01-04 -1.617068  0.548090
2017-01-05 -0.864247  0.419743

iloc 通过行列索引index位置的列表,取几行几列

df.iloc[[1,2,4],[0,2]])
                   A         C
2017-01-02  0.085091  0.568128
2017-01-03  0.729076 -0.451151
2017-01-05 -1.281975 -0.190119

iat 通过行列索引index位置快速访问标量(等同于先前的方法)

df.iat[1,1]
-0.170996002652

布尔索引

通过单列的值是否满足条件,来选择数据

df[df.A > 0]  # A列的值大于0的数据
                   A         B         C         D
2017-01-03  0.276486 -1.003779  0.721863 -0.558061
2017-01-04  1.177206 -0.464778 -0.116442 -0.385712
2017-01-06  0.846665 -1.398207 -0.145356  0.924342

从满足布尔条件的DataFrame中选择值

df[df > 0]
                   A         B         C         D
2017-01-01       NaN  1.963213  0.643244  0.945643
2017-01-02  0.364237  0.917368       NaN       NaN
2017-01-03  0.702624       NaN  0.088565       NaN
2017-01-04  1.274313       NaN  2.313910       NaN
2017-01-05  2.586315  0.588273       NaN  1.482597
2017-01-06       NaN  0.405928  0.309201       NaN

使用isin()方法进行过滤

df2 = df.copy()
df2['E'] = ['one', 'one','two','three','four','three']
df2[df2['E'].isin(['two','four'])]
                   A         B         C         D      E
2017-01-01  0.723399 -0.369247  0.863941 -1.910875    one
2017-01-02 -0.047573 -0.609780  2.130650 -0.019281    one
2017-01-03 -0.566122 -0.850374 -0.031516  0.362023    two
2017-01-04  0.903819 -0.513673  0.118850 -0.351811  three
2017-01-05 -0.485232 -0.864457  1.396835 -1.696083   four
2017-01-06  0.272145 -0.644449 -1.319063 -0.201354  three
============= start to filter =============== 
                   A         B         C         D     E
2017-01-03 -0.566122 -0.850374 -0.031516  0.362023   two
2017-01-05 -0.485232 -0.864457  1.396835 -1.696083  four

如果使用IPython,则会自动启用列名(以及公共属性)的选项完成。 以下是将要完成的属性的一个子集:

In [13]: df2.<TAB>
df2.A                  df2.bool
df2.abs                df2.boxplot
df2.add                df2.C
df2.add_prefix         df2.clip
df2.add_suffix         df2.clip_lower
df2.align              df2.clip_upper
df2.all                df2.columns
df2.any                df2.combine
df2.append             df2.combine_first
df2.apply              df2.compound
df2.applymap           df2.consolidate
df2.D

可以看到,列ABCD自动标签完成。E也在一样。其余的属性为了简洁而被截短。

//原文出自【易百教程】,商业转载请联系作者获得授权,非商业转载请保留原文链接:https://www.yiibai.com/pandas/python_pandas_series.html

DataFrame 操作

pandas.DataFrame( data, index, columns, dtype, copy)
参数 描述
data 数据,如:ndarrayseriesmaplistdictconstant和另一个DataFrame
index 缺省值np.arrange(n)
columns 缺省值np.arrange(n)
dtype 每列的数据类型
copy 如果默认值为False,用于复制数据。

创建DataFrame

DataFrame 可以使用各种输入创建 :

  • 列表
  • 字典
  • 系列
  • Numpy ndarrays
  • 另一个数据帧(DataFrame)

创建一个空的DataFrame

df = pd.DataFrame()

从列表创建DataFrame

data = [1,2,3,4,5]
df = pd.DataFrame(data)
     0
0    1
1    2
2    3
3    4
4    5
data = [['Alex',10],['Bob',12],['Clarke',13]]
df = pd.DataFrame(data,columns=['Name','Age'])
df = pd.DataFrame(data,columns=['Name','Age'],dtype=float)  
# dtype参数将Age列的类型更改为浮点。
      Name      Age
0     Alex      10
1     Bob       12
2     Clarke    13

      Name     Age
0     Alex     10.0
1     Bob      12.0
2     Clarke   13.0

从ndarrays/Lists的字典来创建DataFrame

所有的ndarrays必须具有相同的长度。如果传递了索引(index),则索引的长度应等于数组的长度。

列表的长度必须一致,必要时用 np.nan 补全。

data = {'Name':['Tom', 'Jack', 'Steve', 'Ricky'],'Age':[28,34,29,42]}
data = {'Name':['Tom', 'Jack', 'Steve', 'Ricky'],'Age':[28,34,29,np.nan]}
df = pd.DataFrame(data, index=['rank1','rank2','rank3','rank4'])
      Age      Name
0     28        Tom
1     34       Jack
2     29      Steve
3     42      Ricky

         Age    Name
rank1    28      Tom
rank2    34     Jack
rank3    29    Steve
rank4    42    Ricky

从列表创建数据帧DataFrame

字典列表可作为输入数据传递以用来创建数据帧(DataFrame),字典键默认为列名。

data = [{'a': 1, 'b': 2},{'a': 5, 'b': 10, 'c': 20}]
# NaN被填充到key缺失的区域。
df = pd.DataFrame(data)
df = pd.DataFrame(data, index=['first', 'second'])
    a    b      c
0   1   2     NaN
1   5   10   20.0

        a   b       c
first   1   2     NaN
second  5   10   20.0
data = [{'a': 1, 'b': 2},{'a': 5, 'b': 10, 'c': 20}]
df1 = pd.DataFrame(data, index=['first', 'second'], columns=['a', 'b'])
df2 = pd.DataFrame(data, index=['first', 'second'], columns=['a', 'b1'])
         a  b
first    1  2
second   5  10

         a  b1
first    1  NaN
second   5  NaN

从系列的字典来创建DataFrame

字典的系列可以传递以形成一个DataFrame。 所得到的索引是通过的所有系列索引的并集。

d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']),
      'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])}
df = pd.DataFrame(d)
      one    two
a     1.0    1
b     2.0    2
c     3.0    3
d     NaN    4

添加列

# 跟字典有点像
df['three']=pd.Series([10,20,30],index=['a','b','c'])
df['four']=df['one']+df['three']
# np.nan + 1 = nan

删除列

del df['one']
df.pop('two')

添加行

df = df.append(df2)

df['bbb']= [1,'2', 3,3,3]

0       int64
aaa     int64
bbb    object
dtype: object

df.iloc[2,1].dtype

dtype('int64')

删除行

使用索引标签从DataFrame中删除或删除行。 如果标签重复,则会删除多行。

df = df.drop(0)

panel

面板(Panel)是3D容的数据。面板数据一词来源于计量经济学,部分源于名称:Pandas - pan(el)-da(ta)-s

3轴(axis)这个名称旨在给出描述涉及面板数据的操作的一些语义。它们是 -

  • items - axis 0,每个项目对应于内部包含的数据帧(DataFrame)。
  • major_axis - axis 1,它是每个数据帧(DataFrame)的索引行。
  • minor_axis - axis 2,它是每个数据帧(DataFrame)的索引列。

Panel 操作

可以使用以下构造函数创建面板 -

pandas.Panel(data, items, major_axis, minor_axis, dtype, copy)

构造函数的参数如下 -

参数 描述
data 数据采取各种形式,如:ndarrayseriesmaplistsdictconstant和另一个数据帧(DataFrame)
items axis=0
major_axis axis=1
minor_axis axis=2
dtype 每列的数据类型
copy 复制数据,默认 - false

2. 创建面板

  • 从ndarrays创建
  • 从DataFrames的dict创建

2.1 从3D ndarray创建

data = np.random.rand(2,4,5)
p = pd.Panel(data)
<class 'pandas.core.panel.Panel'>
Dimensions: 2 (items) x 4 (major_axis) x 5 (minor_axis)
Items axis: 0 to 1
Major_axis axis: 0 to 3
Minor_axis axis: 0 to 4

2.2 从DataFrame对象的dict创建面板

data = {'Item1' : pd.DataFrame(np.random.randn(4, 3)), 
        'Item2' : pd.DataFrame(np.random.randn(4, 2))}
p = pd.Panel(data)
<class 'pandas.core.panel.Panel'>
Dimensions: 2 (items) x 4 (major_axis) x 5 (minor_axis)
Items axis: 0 to 1
Major_axis axis: 0 to 3
Minor_axis axis: 0 to 4

2.3 创建一个空面板

p = pd.Panel()
<class 'pandas.core.panel.Panel'>
Dimensions: 0 (items) x 0 (major_axis) x 0 (minor_axis)
Items axis: None
Major_axis axis: None
Minor_axis axis: None

3. 从面板中选择数据

要从面板中选择数据,可以使用以下方式 -

  • Items
  • Major_axis
  • Minor_axis

使用Items

data = {'Item1' : pd.DataFrame(np.random.randn(4, 3)), 
        'Item2' : pd.DataFrame(np.random.randn(4, 2))}
p = pd.Panel(data)
print p['Item1']
            0          1          2
0    0.488224  -0.128637   0.930817
1    0.417497   0.896681   0.576657
2   -2.775266   0.571668   0.290082
3   -0.400538  -0.144234   1.110535

使用major_axis

# creating an empty panel
import pandas as pd
import numpy as np
data = {'Item1' : pd.DataFrame(np.random.randn(4, 3)), 
        'Item2' : pd.DataFrame(np.random.randn(4, 2))}
p = pd.Panel(data)
print p.major_xs(1)

执行上面示例代码,得到以下结果 -

      Item1       Item2
0   0.417497    0.748412
1   0.896681   -0.557322
2   0.576657       NaN

使用minor_axis

data = {'Item1' : pd.DataFrame(np.random.randn(4, 3)), 
        'Item2' : pd.DataFrame(np.random.randn(4, 2))}
p = pd.Panel(data)
print p.minor_xs(1)

执行上面示例代码,得到以下结果 -

       Item1       Item2
0   -0.128637   -1.047032
1    0.896681   -0.557322
2    0.571668    0.431953
3   -0.144234    1.302466

Series 基本功能

属性或方法 描述
axes 返回轴标签列表
dtype 返回对象的数据类型(dtype)
empty 如果系列为空,则返回True
ndim 返回底层数据的维数,默认定义:1
size 返回基础数据中的元素数
values 将系列作为ndarray返回
head() 返回前n
tail() 返回最后n

DataFrame 基本功能

下面来看看数据帧(DataFrame)的基本功能有哪些?下表列出了DataFrame基本功能的重要属性或方法。

属性或方法 描述
T 转置
axes 行轴标签和列轴标签
dtypes 每一列的类型
empty 完全为空,则返回为True,否则False
ndim 维度大小
shape 返回表示DataFrame的维度的元组
size NDFrame中的元素数
values NDFrame的Numpy表示
head() 返回开头前n
tail() 返回最后n

描述性统计

DataFrame聚合函数,轴可以通过名称或整数来指定:

  • 数据帧(DataFrame) : “index”(axis=0,默认),columns(axis=1)

axis=1 实例

df.sum(1)

pandas 数据类型分为:数字类型和object。object即python对象,字符串等。

str 不能与 数字 相加。通常一列的类型相同。也可以不同,但是不科学。

函数

编号 函数 描述
1 count() 非空数量
2 sum() 所有值之和
3 mean() 所有值的平均值
4 median() 所有值的中位数
5 mode() 值的模值
6 std() 值的标准偏差
7 min() 所有值中的最小值
8 max() 所有值中的最大值
9 abs() 绝对值
10 prod() 数组元素的乘积
11 cumsum() 累计总和
12 cumprod() 累计乘积

注 - 由于DataFrame是异构数据结构。通用操作不适用于所有函数。

  • 类似于:sum()cumsum()函数能与数字和字符(或)字符串数据元素一起工作,不会产生任何错误。字符聚合从来都比较少被使用,虽然这些函数不会引发任何异常。
  • 由于这样的操作无法执行,因此,当DataFrame包含字符或字符串数据时,像abs()cumprod()这样的函数会抛出异常。

汇总数据

describe()函数是用来计算有关DataFrame列的统计信息的摘要。

df.describe()
               Age         Rating
count    12.000000      12.000000
mean     31.833333       3.743333
std       9.232682       0.661628
min      23.000000       2.560000
25%      25.000000       3.230000
50%      29.500000       3.790000
75%      35.500000       4.132500
max      51.000000       4.800000

该函数给出了平均值,标准差和IQR值。 而且,函数排除字符列,并给出关于数字列的摘要。 include是用于传递关于什么列需要考虑用于总结的必要信息的参数。获取值列表; 默认情况下是”数字值”。

  • object - 汇总字符串列
  • number - 汇总数字列
  • all - 将所有列汇总在一起(不应将其作为列表值传递)

现在,在程序中使用以下语句并检查输出 -

df.describe(include=['object'])

表格函数应用

  • 表合理函数应用:pipe()
  • 行或列函数应用:apply()
  • 元素函数应用:applymap()

DataFrame中的所有元素相加一个值2

def adder(ele1,ele2):
   return ele1+ele2

df = pd.DataFrame(np.random.randn(5,3),columns=['col1','col2','col3'])
df = df.pipe(adder,2)

行或列合理函数应用

可以使用apply()方法沿DataFramePanel的轴应用任意函数。 默认情况下,操作按列执行,将每列列为数组。

df = pd.DataFrame(np.random.randn(5,3),columns=['col1','col2','col3'])
df = df.apply(np.mean)

通过传递axis参数,可以在行上执行操作。

df = pd.DataFrame(np.random.randn(5,3),columns=['col1','col2','col3'])
df = df.apply(np.mean,axis=1)

元素合理函数应用

并不是所有的函数都可以向量化(也不是返回另一个数组的NumPy数组,也不是任何值),在DataFrame上的方法applymap()和类似于在Series上的map()接受任何Python函数,并且返回单个值。

map :让一行执行函数
df = pd.DataFrame(np.random.randn(5,3),columns=['col1','col2','col3'])
df = df['col1'].map(lambda x:x*100)
0     14.439581
1    163.536125
2     88.995853
3    -31.210458
4    -73.832149
applymap : 每一个值都执行函数
df = pd.DataFrame(np.random.randn(5,3),columns=['col1','col2','col3'])
df = df.applymap(lambda x:x*100)

重建索引

可以通过索引来实现多个操作

  • 重新排序现有数据以匹配一组新的标签。
  • 在没有标签数据的标签位置插入缺失值(NA)标记。

reindex 重建索引

N=20

df = pd.DataFrame({
   'A': pd.date_range(start='2016-01-01',periods=N,freq='D'),
   'x': np.linspace(0,stop=N-1,num=N),
   'y': np.random.rand(N),
   'C': np.random.choice(['Low','Medium','High'],N).tolist(),
   'D': np.random.normal(100, 10, size=(N)).tolist()
})

df_reindexed = df.reindex(index=[0,2,5], columns=['A', 'C', 'B'])

执行上面示例代码,得到以下结果 -

            A    C     B
0  2016-01-01  Low   NaN
2  2016-01-03  High  NaN
5  2016-01-06  Low   NaN

reindex_like 重建索引与其他对象对齐

有时可能希望采取一个对象和重新索引,其轴被标记为与另一个对象相同。

df1 = pd.DataFrame(np.random.randn(10,3),columns=['col1','col2','col3'])
df2 = pd.DataFrame(np.random.randn(7,3),columns=['col1','col2','col3'])

df1 = df1.reindex_like(df2)
          col1         col2         col3
0    -2.467652    -1.211687    -0.391761
1    -0.287396     0.522350     0.562512
2    -0.255409    -0.483250     1.866258
3    -1.150467    -0.646493    -0.222462
4     0.152768    -2.056643     1.877233
5    -1.155997     1.528719    -1.343719
6    -1.015606    -1.245936    -0.295275

填充时重新加注

reindex()采用可选参数方法,它是一个填充方法,其值如下:

  • pad/ffill - 向前填充值
  • bfill/backfill - 向后填充值
  • nearest - 从最近的索引值填充
df1 = pd.DataFrame(np.random.randn(6,3),columns=['col1','col2','col3'])
df2 = pd.DataFrame(np.random.randn(2,3),columns=['col1','col2','col3'])

print df2.reindex_like(df1)
print df2.reindex_like(df1,method='ffill')

执行上面示例代码时,得到以下结果 -

         col1        col2       col3
0    1.311620   -0.707176   0.599863
1   -0.423455   -0.700265   1.133371
2         NaN         NaN        NaN
3         NaN         NaN        NaN
4         NaN         NaN        NaN
5         NaN         NaN        NaN

Data Frame with Forward Fill:
         col1        col2        col3
0    1.311620   -0.707176    0.599863
1   -0.423455   -0.700265    1.133371
2   -0.423455   -0.700265    1.133371
3   -0.423455   -0.700265    1.133371
4   -0.423455   -0.700265    1.133371
5   -0.423455   -0.700265    1.133371

注 - 最后四行被填充了。

重建索引时的填充限制

限制参数在重建索引时提供对填充的额外控制。限制指定连续匹配的最大计数。

df1 = pd.DataFrame(np.random.randn(6,3),columns=['col1','col2','col3'])
df2 = pd.DataFrame(np.random.randn(2,3),columns=['col1','col2','col3'])

print df2.reindex_like(df1)
print df2.reindex_like(df1,method='ffill',limit=1)

在执行上面示例代码时,得到以下结果 -

         col1        col2        col3
0    0.247784    2.128727    0.702576
1   -0.055713   -0.021732   -0.174577
2         NaN         NaN         NaN
3         NaN         NaN         NaN
4         NaN         NaN         NaN
5         NaN         NaN         NaN

Data Frame with Forward Fill limiting to 1:
         col1        col2        col3
0    0.247784    2.128727    0.702576
1   -0.055713   -0.021732   -0.174577
2   -0.055713   -0.021732   -0.174577
3         NaN         NaN         NaN
4         NaN         NaN         NaN
5         NaN         NaN         NaN

注意 - 只有一行被填充。 然后,其它行按原样保留。

重命名

rename()方法允许基于一些映射(字典或者系列)或任意函数来重新标记一个轴。

rename()方法提供了一个inplace命名参数,默认为False并复制底层数据。 指定传递inplace = True则表示将数据本身重命名。

df1 = pd.DataFrame(np.random.randn(6,3),columns=['col1','col2','col3'])
print df1.rename(columns={'col1' : 'c1', 'col2' : 'c2'},
index = {0 : 'apple', 1 : 'banana', 2 : 'durian'})
         col1        col2        col3
0    0.486791    0.105759    1.540122
1   -0.990237    1.007885   -0.217896
2   -0.483855   -1.645027   -1.194113
3   -0.122316    0.566277   -0.366028
4   -0.231524   -0.721172   -0.112007
5    0.438810    0.000225    0.435479

                c1          c2        col3
apple     0.486791    0.105759    1.540122
banana   -0.990237    1.007885   -0.217896
durian   -0.483855   -1.645027   -1.194113
3        -0.122316    0.566277   -0.366028
4        -0.231524   -0.721172   -0.112007
5         0.438810    0.000225    0.435479

迭代

Pandas对象之间的基本迭代的行为取决于类型。当迭代一个系列时,它被视为数组式,基本迭代产生这些值。其他数据结构,如:DataFramePanel,遵循类似惯例迭代对象的键。

简而言之,基本迭代(对于i在对象中)产生

  • Series - 值

  • DataFrame - 列标签

  • Pannel - 项目标签

迭代DataFrame

迭代DataFrame提供列名。现在来看看下面的例子来理解这个概念。

for col in df:  # 列标签
   print (col)

执行上面示例代码,得到以下结果 -

A
C
D
x
y

要遍历数据帧(DataFrame)中的行,可以使用以下函数

  • iteritems() - 迭代(列,列值)
  • iterrows() - 将行迭代为(行索引,行值)对
  • itertuples() - 以namedtuples的形式迭代行

iteritems()示例

列作为键,列值迭代为Series对象

df = pd.DataFrame(np.random.randn(4,3),columns=['col1','col2','col3'])
for key,value in df.iteritems():
   print (key,value)
col1 0    0.802390
1    0.324060
2    0.256811
3    0.839186
Name: col1, dtype: float64

col2 0    1.624313
1   -1.033582
2    1.796663
3    1.856277
Name: col2, dtype: float64

col3 0   -0.022142
1   -0.230820
2    1.160691
3   -0.830279
Name: col3, dtype: float64
Shell

iterrows()示例

iterrows()返回迭代器,产生每个索引值以及包含每行数据的序列。

df = pd.DataFrame(np.random.randn(4,3),columns = ['col1','col2','col3'])
for row_index,row in df.iterrows():
   print (row_index,row)
0  col1    1.529759
   col2    0.762811
   col3   -0.634691
Name: 0, dtype: float64

1  col1   -0.944087
   col2    1.420919
   col3   -0.507895
Name: 1, dtype: float64

2  col1   -0.077287
   col2   -0.858556
   col3   -0.663385
Name: 2, dtype: float64
3  col1    -1.638578
   col2     0.059866
   col3     0.493482
Name: 3, dtype: float64
Shell

注意 - 由于iterrows()遍历行,因此不会跨该行保留数据类型。0,1,2是行索引,col1col2col3是列索引。

itertuples()示例

itertuples()方法将为DataFrame中的每一行返回一个产生一个命名元组的迭代器。元组的第一个元素将是行的相应索引值,而剩余的值是行值。

df = pd.DataFrame(np.random.randn(4,3),columns = ['col1','col2','col3'])
for row in df.itertuples():
    print (row)
Pandas(Index=0, col1=1.5297586201375899, col2=0.76281127433814944, col3=-
0.6346908238310438)

Pandas(Index=1, col1=-0.94408735763808649, col2=1.4209186418359423, col3=-
0.50789517967096232)

Pandas(Index=2, col1=-0.07728664756791935, col2=-0.85855574139699076, col3=-
0.6633852507207626)

Pandas(Index=3, col1=0.65734942534106289, col2=-0.95057710432604969,
col3=0.80344487462316527)
Shell

注意 - 不要尝试在迭代时修改任何对象。迭代是用于读取,迭代器返回原始对象(视图)的副本,因此更改将不会反映在原始对象上。

df = pd.DataFrame(np.random.randn(4,3),columns = ['col1','col2','col3'])
for index, row in df.iterrows():
   row['a'] = 10
print (df)

执行上面示例代码,得到以下结果 -

        col1       col2       col3
0  -1.739815   0.735595  -0.295589
1   0.635485   0.106803   1.527922
2  -0.939064   0.547095   0.038585
3  -1.016509  -0.116580  -0.523158

注意观察结果,修改变化并未反映出来。

排序

Pandas有两种排序方式:

  • 按标签
  • 按实际值

按标签排序

# axis 默认为0,即按照行索引排序;1按照列排序。默认升序。
sorted_df=unsorted_df.sort_index()
# ascending=False:按照降序;反之,正序。
sorted_df=unsorted_df.sort_index(ascending=False,axis=1)

按值排序

# 通过by参数指定需要列值
sorted_df = un_df.sort_values(by='col1')
sorted_df = un_df.sort_values(by=['col1','col2'])
sorted_df=un_df.sort_values(by=['col1'],ascending=False)

排序算法

sort_values()提供了:mergeesortheapsortquicksort中选择算法的一个配置。Mergesort是唯一稳定的算法。

sorted_df=unsorted_df.sort_values(by='col1',kind='mergesort')

字符串和文本数据

Pandas提供了一组字符串函数,可以方便地对字符串数据进行操作。 最重要的是,这些函数忽略(或排除)丢失/NaN值。

几乎这些方法都使用Python字符串函数(请参阅: http://docs.python.org/3/library/stdtypes.html#string-methods )。 因此,将Series对象转换为String对象,然后执行函数。

函数 描述
lower() Series/Index中的字符串转换为小写。
upper() Series/Index中的字符串转换为大写。
len() 计算字符串长度。
strip() 帮助从两侧的系列/索引中的每个字符串中删除空格(包括换行符)。
split(' ') 用给定的模式拆分每个字符串。
cat(sep=' ') 使用给定的分隔符连接系列/索引元素。
get_dummies() 返回具有单热编码值的数据帧(DataFrame)。
contains(pattern) 如果元素中包含子字符串,则返回每个元素的布尔值True,否则为False
replace(a,b) 将值a替换为值b
repeat(value) 重复每个元素指定的次数。
count(pattern) 返回模式中每个元素的出现总数。
startswith(pattern) 如果系列/索引中的元素以模式开始,则返回true
endswith(pattern) 如果系列/索引中的元素以模式结束,则返回true
find(pattern) 返回模式第一次出现的位置。
findall(pattern) 返回模式的所有出现的列表。
swapcase 变换字母大小写。
islower() 检查系列/索引中每个字符串中的所有字符是否小写,返回布尔值
isupper() 检查系列/索引中每个字符串中的所有字符是否大写,返回布尔值
isnumeric() 检查系列/索引中每个字符串中的所有字符是否为数字,返回布尔值。
s.str.lower()
s.str.upper()
s.str.swapcase()
s.str.islower()
s.str.isupper()
s.str.isnumeric()
s.str.len()
s.str.strip()
s.str.split(' ')
s.str.replace('@','$')
s.str.count('m')
s.str.cat(sep=' <=> ')
# Tom  <=>  William Rick <=> John <=> Alber@t
s.str.get_dummies()
"""
    William Rick  Alber@t  John  Tom 
0              0        0     0     1
1              1        0     0     0
2              0        0     1     0
3              0        1     0     0
"""
s.str.contains(' ')
"""
0     True
1     True
2    False
3    False
dtype: bool
"""
s.str.repeat(2)
"""
0                      Tom Tom 
1     William Rick William Rick
2                      JohnJohn
3                Alber@tAlber@t
dtype: object
"""
s.str.find('e')  # 第一个匹配的索引,-1表示元素中没有这样的模式可用。
"""
0   -1
1   -1
2   -1
3    3
dtype: int64
"""
s.str.findall('e')  # 找到所有的匹配列表,空列表([])表示元素中没有这样的模式可用。
"""
0     []
1     []
2     []
3    [e]
dtype: object
"""

Pandas选项和自定义

Pandas提供API来自定义其行为的某些方面,大多使用来显示。

API由五个相关函数组成。

  • get_option()
  • set_option()
  • reset_option()
  • describe_option()
  • option_context()

get_option(param)

获取如下值:

display.max_rows

显示上限的行

print(pd.get_option("display.max_rows"))

display.max_columns

显示上限的列

print (pd.get_option("display.max_columns")

set_option(param,value)

设置如下的值:

使用set_option(),可以更改要显示的默认行数。

pd.set_option("display.max_rows",80)
pd.set_option("display.max_columns",32)

reset_option(param)

display.max_rows

重置如下值为默认值:

pd.reset_option("display.max_rows")

describe_option(param)

打印如下值参数的描述。

pd.describe_option("display.max_rows")

option_context()

option_context上下文管理器用于临时设置语句中的选项。当退出使用块时,选项值将自动恢复。

# 临时设置该值,退出代码块临时值不生效
with pd.option_context("display.max_rows",10):
   print(pd.get_option("display.max_rows"))
print(pd.get_option("display.max_rows"))

常用参数:

编号 参数 描述
1 display.max_rows 要显示的最大行数
2 display.max_columns 要显示的最大列数
3 display.expand_frame_repr 显示数据帧以拉伸页面
4 display.max_colwidth 显示最大列宽
5 display.precision 显示十进制数的精度

选择数据

编号 索引 描述
1 .loc() 基于标签
2 .iloc() 基于整数
3 .ix() 基于标签和整数

.loc()

包括起始边界。整数是有效的标签,但它们是指标签而不是位置。

print (df.loc[:,'A'])
print (df.loc[:,['A','C']])
print (df.loc['a':'h'])
print (df.loc['a']>0)

.iloc()

print (df.iloc[:4])
print (df.iloc[1:5, 2:4])
print (df.iloc[[1, 3, 5], [1, 3]])

.ix()

除了基于纯标签和整数之外,Pandas还提供了一种使用.ix()运算符进行选择和子集化对象的混合方法。

print (df.ix[:4])
          A         B         C         D
0 -1.449975 -0.002573  1.349962  0.539765
1 -1.249462 -0.800467  0.483950  0.187853
2  1.361273 -1.893519  0.307613 -0.119003
3 -0.103433 -1.058175 -0.587307 -0.114262
4 -0.612298  0.873136 -0.607457  1.047772
print (df.ix[:,'A'])

使用符号

使用多轴索引从Pandas对象获取值可使用以下符号 -

对象 索引 描述
Series s.loc[indexer] 标量值
DataFrame df.loc[row_index,col_index] 标量对象
Panel p.loc[item_index,major_index, minor_index] p.loc[item_index,major_index, minor_index]

注意 - .iloc().ix()应用相同的索引选项和返回值。

现在来看看如何在DataFrame对象上执行每个操作。这里使用基本索引运算符[]

print (df['A'])
print (df[2:2])
Empty DataFrame
Columns: [A, B, C, D]
Index: []

属性访问

可以使用属性运算符.来选择列。

print (df.A)

统计函数

统计方法有助于理解和分析数据的行为。现在我们将学习一些统计函数,可以将这些函数应用到Pandas的对象上。

pct_change()函数

系列,DatFrames和Panel都有pct_change()函数。此函数将每个元素与其前一个元素进行比较,并计算变化百分比。

import pandas as pd
import numpy as np
s = pd.Series([1,2,3,4,5,4])
print (s.pct_change())

df = pd.DataFrame(np.random.randn(5, 2))
print (df.pct_change())
Python

执行上面示例代码,得到以下结果 -

0        NaN
1   1.000000
2   0.500000
3   0.333333
4   0.250000
5  -0.200000
dtype: float64

            0          1
0         NaN        NaN
1  -15.151902   0.174730
2  -0.746374   -1.449088
3  -3.582229   -3.165836
4   15.601150  -1.860434
Shell

默认情况下,pct_change()对列进行操作; 如果想应用到行上,那么可使用axis = 1参数。

协方差

协方差适用于系列数据。Series对象有一个方法cov用来计算序列对象之间的协方差。NA将被自动排除。

Cov系列示例

import pandas as pd
import numpy as np
s1 = pd.Series(np.random.randn(10))
s2 = pd.Series(np.random.randn(10))
print (s1.cov(s2))
Python

执行上面示例代码,得到以下结果 -

0.0667296739178
Python

当应用于DataFrame时,协方差方法计算所有列之间的协方差(cov)值。

import pandas as pd
import numpy as np
frame = pd.DataFrame(np.random.randn(10, 5), columns=['a', 'b', 'c', 'd', 'e'])
print (frame['a'].cov(frame['b']))
print (frame.cov())
Python

执行上面示例代码,得到以下结果 -

-0.406796939839
          a         b         c         d         e
a  0.784886 -0.406797  0.181312  0.513549 -0.597385
b -0.406797  0.987106 -0.662898 -0.492781  0.388693
c  0.181312 -0.662898  1.450012  0.484724 -0.476961
d  0.513549 -0.492781  0.484724  1.571194 -0.365274
e -0.597385  0.388693 -0.476961 -0.365274  0.785044
Shell

注 - 观察第一个语句中ab列之间的cov结果值,与由DataFrame上的cov返回的值相同。

相关性

相关性显示了任何两个数值(系列)之间的线性关系。有多种方法来计算pearson(默认),spearmankendall之间的相关性。

import pandas as pd
import numpy as np
frame = pd.DataFrame(np.random.randn(10, 5), columns=['a', 'b', 'c', 'd', 'e'])

print (frame['a'].corr(frame['b']))
print (frame.corr())
Python

执行上面示例代码,得到以下结果 -

-0.613999376618
          a         b         c         d         e
a  1.000000 -0.613999 -0.040741 -0.227761 -0.192171
b -0.613999  1.000000  0.012303  0.273584  0.591826
c -0.040741  0.012303  1.000000 -0.391736 -0.470765
d -0.227761  0.273584 -0.391736  1.000000  0.364946
e -0.192171  0.591826 -0.470765  0.364946  1.000000
Shell

如果DataFrame中存在任何非数字列,则会自动排除。

数据排名

数据排名为元素数组中的每个元素生成排名。在关系的情况下,分配平均等级。

import pandas as pd
import numpy as np
s = pd.Series(np.random.randn(5), index=list('abcde'))

s['d'] = s['b'] # so there's a tie

print (s.rank())
Python

执行上面示例代码,得到以下结果 -

a    4.0
b    1.5
c    3.0
d    1.5
e    5.0
dtype: float64
Shell

Rank可选地使用一个默认为true的升序参数; 当错误时,数据被反向排序,也就是较大的值被分配较小的排序。

Rank支持不同的tie-breaking方法,用方法参数指定 -

  • average - 并列组平均排序等级
  • min - 组中最低的排序等级
  • max - 组中最高的排序等级
  • first - 按照它们出现在数组中的顺序分配队列

Pandas窗口函数

为了处理数字数据,Pandas提供了几个变体,如滚动,展开和指数移动窗口统计的权重。 其中包括总和,均值,中位数,方差,协方差,相关性等。

下来学习如何在DataFrame对象上应用上提及的每种方法。

.rolling()函数

这个函数可以应用于一系列数据。指定window=n参数并在其上应用适当的统计函数。

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(10, 4),
index = pd.date_range('1/1/2020', periods=10),
columns = ['A', 'B', 'C', 'D'])

print (df.rolling(window=3).mean())
Python

执行上面示例代码,得到以下结果 -

                   A         B         C         D
2020-01-01       NaN       NaN       NaN       NaN
2020-01-02       NaN       NaN       NaN       NaN
2020-01-03 -0.306293  0.214001 -0.076004 -0.200793
2020-01-04  0.236632 -0.437033  0.046111 -0.252062
2020-01-05  0.761818 -0.181635 -0.546929 -0.738482
2020-01-06  1.306498 -0.411834 -0.680948 -0.070285
2020-01-07  0.956877 -0.749315 -0.503484  0.160620
2020-01-08  0.354319 -1.067165 -1.238036  1.051048
2020-01-09  0.262081 -0.898373 -1.059351  0.342291
2020-01-10  0.326801 -0.350519 -1.064437  0.749869
Shell

注 - 由于窗口大小为3(window),前两个元素有空值,第三个元素的值将是nn-1n-2元素的平均值。这样也可以应用上面提到的各种函数了。

.expanding()函数

这个函数可以应用于一系列数据。 指定min_periods = n参数并在其上应用适当的统计函数。

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(10, 4),
      index = pd.date_range('1/1/2018', periods=10),
      columns = ['A', 'B', 'C', 'D'])
print (df.expanding(min_periods=3).mean())
Python

执行上面示例代码得到以下结果 -

                   A         B         C         D
2018-01-01       NaN       NaN       NaN       NaN
2018-01-02       NaN       NaN       NaN       NaN
2018-01-03 -0.425085 -0.124270 -0.324134 -0.234001
2018-01-04 -0.293824 -0.038188 -0.172855  0.447226
2018-01-05 -0.516146 -0.013441 -0.384935  0.379267
2018-01-06 -0.614905  0.290308 -0.594635  0.414396
2018-01-07 -0.606090  0.121265 -0.604148  0.246296
2018-01-08 -0.597291  0.075374 -0.425182  0.092831
2018-01-09 -0.380505  0.074956 -0.253081  0.146426
2018-01-10 -0.235030  0.018936 -0.259566  0.315200
Shell

.ewm()函数

ewm()可应用于系列数据。指定comspanhalflife参数,并在其上应用适当的统计函数。它以指数形式分配权重。

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(10, 4),
   index = pd.date_range('1/1/2019', periods=10),
   columns = ['A', 'B', 'C', 'D'])
print (df.ewm(com=0.5).mean())
Python

执行上面示例函数,得到以下结果 -

                   A         B         C         D
2019-01-01  1.047165  0.777385 -1.286948 -0.080564
2019-01-02  0.484093 -0.630998 -0.975172 -0.117832
2019-01-03  0.056189  0.830492  0.116325  1.005547
2019-01-04 -0.363824  1.222173  0.497901 -0.235209
2019-01-05 -0.260685  1.066029  0.391480  1.196190
2019-01-06  0.389649  1.458152 -0.231936 -0.481003
2019-01-07  1.071035 -0.016003  0.387420 -0.170811
2019-01-08 -0.573686  1.052081  1.218439  0.829366
2019-01-09  0.222927  0.556430  0.811838 -0.562096
2019-01-10  0.224624 -1.225446  0.204961 -0.800444
Shell

窗口函数主要用于通过平滑曲线来以图形方式查找数据内的趋势。如果日常数据中有很多变化,并且有很多数据点可用,那么采样和绘图就是一种方法,应用窗口计算并在结果上绘制图形是另一种方法。 通过这些方法,可以平滑曲线或趋势。

Pandas聚合

当有了滚动,扩展和ewm对象创建了以后,就有几种方法可以对数据执行聚合。

DataFrame应用聚合

让我们创建一个DataFrame并在其上应用聚合。

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(10, 4),
      index = pd.date_range('1/1/2019', periods=10),
      columns = ['A', 'B', 'C', 'D'])

print (df)
print("=======================================")
r = df.rolling(window=3,min_periods=1)
print (r)
Python

执行上面示例代码,得到以下结果 -

                   A         B         C         D
2019-01-01 -0.901602 -1.778484  0.728295 -0.758108
2019-01-02 -0.826162  0.994140  0.976164 -0.918249
2019-01-03  0.260841  0.905993  1.505967 -0.124883
2019-01-04 -0.112230 -0.111885  0.702712 -0.871768
2019-01-05 -0.239969  1.435918 -0.160140 -0.547702
2019-01-06 -0.126897 -2.628206 -0.280658  0.167422
2019-01-07  0.367903  0.994337 -0.529830  0.195990
2019-01-08 -0.530872 -0.384915 -0.397150 -0.024074
2019-01-09 -0.418925  0.049046 -0.816616  0.308107
2019-01-10 -0.176857  2.573145  0.010211 -1.427078
=======================================
Rolling [window=3,min_periods=1,center=False,axis=0]
Shell

可以通过向整个DataFrame传递一个函数来进行聚合,或者通过标准的获取项目方法来选择一个列。

在整个数据框上应用聚合

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(10, 4),
      index = pd.date_range('1/1/2000', periods=10),
      columns = ['A', 'B', 'C', 'D'])
print df

r = df.rolling(window=3,min_periods=1)
print r.aggregate(np.sum)
Python

执行示例代码,得到以下结果 -

                   A         B         C         D
2020-01-01  1.069090 -0.802365 -0.323818 -1.994676
2020-01-02  0.190584  0.328272 -0.550378  0.559738
2020-01-03  0.044865  0.478342 -0.976129  0.106530
2020-01-04 -1.349188 -0.391635 -0.292740  1.412755
2020-01-05  0.057659 -1.331901 -0.297858 -0.500705
2020-01-06  2.651680 -1.459706 -0.726023  0.294283
2020-01-07  0.666481  0.679205 -1.511743  2.093833
2020-01-08 -0.284316 -1.079759  1.433632  0.534043
2020-01-09  1.115246 -0.268812  0.190440 -0.712032
2020-01-10 -0.121008  0.136952  1.279354  0.275773
============================================
                   A         B         C         D
2020-01-01  1.069090 -0.802365 -0.323818 -1.994676
2020-01-02  1.259674 -0.474093 -0.874197 -1.434938
2020-01-03  1.304539  0.004249 -1.850326 -1.328409
2020-01-04 -1.113739  0.414979 -1.819248  2.079023
2020-01-05 -1.246664 -1.245194 -1.566728  1.018580
2020-01-06  1.360151 -3.183242 -1.316621  1.206333
2020-01-07  3.375821 -2.112402 -2.535624  1.887411
2020-01-08  3.033846 -1.860260 -0.804134  2.922160
2020-01-09  1.497411 -0.669366  0.112329  1.915845
2020-01-10  0.709922 -1.211619  2.903427  0.097785
Shell

在数据框的单个列上应用聚合

示例代码

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(10, 4),
      index = pd.date_range('1/1/2000', periods=10),
      columns = ['A', 'B', 'C', 'D'])
print (df)
print("====================================")
r = df.rolling(window=3,min_periods=1)
print (r['A'].aggregate(np.sum))
Python

执行上面示例代码,得到以下结果 -

                   A         B         C         D
2000-01-01 -1.095530 -0.415257 -0.446871 -1.267795
2000-01-02 -0.405793 -0.002723  0.040241 -0.131678
2000-01-03 -0.136526  0.742393 -0.692582 -0.271176
2000-01-04  0.318300 -0.592146 -0.754830  0.239841
2000-01-05 -0.125770  0.849980  0.685083  0.752720
2000-01-06  1.410294  0.054780  0.297992 -0.034028
2000-01-07  0.463223 -1.239204 -0.056420  0.440893
2000-01-08 -2.244446 -0.516937 -2.039601 -0.680606
2000-01-09  0.991139  0.026987 -2.391856  0.585565
2000-01-10  0.112228 -0.701284 -1.139827  1.484032
====================================
2000-01-01   -1.095530
2000-01-02   -1.501323
2000-01-03   -1.637848
2000-01-04   -0.224018
2000-01-05    0.056004
2000-01-06    1.602824
2000-01-07    1.747747
2000-01-08   -0.370928
2000-01-09   -0.790084
2000-01-10   -1.141079
Freq: D, Name: A, dtype: float64
Shell

在DataFrame的多列上应用聚合

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(10, 4),
      index = pd.date_range('1/1/2018', periods=10),
      columns = ['A', 'B', 'C', 'D'])
print (df)
print ("==========================================")
r = df.rolling(window=3,min_periods=1)
print (r[['A','B']].aggregate(np.sum))
Python

执行上面示例代码,得到以下结果 -

                   A         B         C         D
2018-01-01  0.518897  0.988917  0.435691 -1.005703
2018-01-02  1.793400  0.130314  2.313787  0.870057
2018-01-03 -0.297601  0.504137 -0.951311 -0.146720
2018-01-04  0.282177  0.142360 -0.059013  0.633174
2018-01-05  2.095398 -0.153359  0.431514 -1.185657
2018-01-06  0.134847  0.188138  0.828329 -1.035120
2018-01-07  0.780541  0.138942 -1.001229  0.714896
2018-01-08  0.579742 -0.642858  0.835013 -1.504110
2018-01-09 -1.692986 -0.861327 -1.125359  0.006687
2018-01-10 -0.263689  1.182349 -0.916569  0.617476
==========================================
                   A         B
2018-01-01  0.518897  0.988917
2018-01-02  2.312297  1.119232
2018-01-03  2.014697  1.623369
2018-01-04  1.777976  0.776811
2018-01-05  2.079975  0.493138
2018-01-06  2.512422  0.177140
2018-01-07  3.010786  0.173722
2018-01-08  1.495130 -0.315777
2018-01-09 -0.332703 -1.365242
2018-01-10 -1.376932 -0.321836
Shell

在DataFrame的单个列上应用多个函数

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(10, 4),
      index = pd.date_range('2019/01/01', periods=10),
      columns = ['A', 'B', 'C', 'D'])
print (df)

print("==========================================")

r = df.rolling(window=3,min_periods=1)
print (r['A'].aggregate([np.sum,np.mean]))
Python

执行上面示例代码,得到以下结果 -

                   A         B         C         D
2019-01-01  1.022641 -1.431910  0.780941 -0.029811
2019-01-02 -0.302858  0.009886 -0.359331 -0.417708
2019-01-03 -1.396564  0.944374 -0.238989 -1.873611
2019-01-04  0.396995 -1.152009 -0.560552 -0.144212
2019-01-05 -2.513289 -1.085277 -1.016419 -1.586994
2019-01-06 -0.513179  0.823411  0.670734  1.196546
2019-01-07 -0.363239 -0.991799  0.587564 -1.100096
2019-01-08  1.474317  1.265496 -0.216486 -0.224218
2019-01-09  2.235798 -1.381457 -0.950745 -0.209564
2019-01-10 -0.061891 -0.025342  0.494245 -0.081681
==========================================
                 sum      mean
2019-01-01  1.022641  1.022641
2019-01-02  0.719784  0.359892
2019-01-03 -0.676780 -0.225593
2019-01-04 -1.302427 -0.434142
2019-01-05 -3.512859 -1.170953
2019-01-06 -2.629473 -0.876491
2019-01-07 -3.389707 -1.129902
2019-01-08  0.597899  0.199300
2019-01-09  3.346876  1.115625
2019-01-10  3.648224  1.216075
Shell

在DataFrame的多列上应用多个函数

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(10, 4),
      index = pd.date_range('2020/01/01', periods=10),
      columns = ['A', 'B', 'C', 'D'])

print (df)
print("==========================================")
r = df.rolling(window=3,min_periods=1)
print (r[['A','B']].aggregate([np.sum,np.mean]))
Python

执行上面示例代码,得到以下结果 -

                   A         B         C         D
2020-01-01  1.053702  0.355985  0.746638 -0.233968
2020-01-02  0.578520 -1.171843 -1.764249 -0.709913
2020-01-03 -0.491185  0.975212  0.200139 -3.372621
2020-01-04 -1.331328  0.776316  0.216623  0.202313
2020-01-05 -1.023147 -0.913686  1.457512  0.999232
2020-01-06  0.995328 -0.979826 -1.063695  0.057925
2020-01-07  0.576668  1.065767 -0.270744 -0.513707
2020-01-08  0.520258  0.969043 -0.119177 -0.125620
2020-01-09 -0.316480  0.549085  1.862249  1.091265
2020-01-10  0.461321 -0.368662 -0.988323  0.543011
==========================================
                   A                   B          
                 sum      mean       sum      mean
2020-01-01  1.053702  1.053702  0.355985  0.355985
2020-01-02  1.632221  0.816111 -0.815858 -0.407929
2020-01-03  1.141037  0.380346  0.159354  0.053118
2020-01-04 -1.243993 -0.414664  0.579686  0.193229
2020-01-05 -2.845659 -0.948553  0.837843  0.279281
2020-01-06 -1.359146 -0.453049 -1.117195 -0.372398
2020-01-07  0.548849  0.182950 -0.827744 -0.275915
2020-01-08  2.092254  0.697418  1.054985  0.351662
2020-01-09  0.780445  0.260148  2.583896  0.861299
2020-01-10  0.665099  0.221700  1.149466  0.383155
Shell

将不同的函数应用于DataFrame的不同列

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(3, 4),
      index = pd.date_range('2020/01/01', periods=3),
      columns = ['A', 'B', 'C', 'D'])
print (df)
print("==========================================")
r = df.rolling(window=3,min_periods=1)
print (r.aggregate({'A' : np.sum,'B' : np.mean}))
Python

执行上面示例代码,得到以下结果 -

                   A         B         C         D
2020-01-01 -0.246302 -0.057202  0.923807 -1.019698
2020-01-02  0.285287  1.467206 -0.368735 -0.397260
2020-01-03 -0.163219 -0.401368  1.254569  0.580188
==========================================
                   A         B
2020-01-01 -0.246302 -0.057202
2020-01-02  0.038985  0.705002
2020-01-03 -0.124234  0.336212

Pandas缺失数据

数据丢失(缺失)在现实生活中总是一个问题。 机器学习和数据挖掘等领域由于数据缺失导致的数据质量差,在模型预测的准确性上面临着严重的问题。 在这些领域,缺失值处理是使模型更加准确和有效的重点。

何时以及为什么数据丢失?

想象一下有一个产品的在线调查。很多时候,人们不会分享与他们有关的所有信息。 很少有人分享他们的经验,但不是他们使用产品多久; 很少有人分享使用产品的时间,经验,但不是他们的个人联系信息。 因此,以某种方式或其他方式,总会有一部分数据总是会丢失,这是非常常见的现象。

如何处理使用Pandas的缺失值(如NANaN)。

检测缺失值

isnull()notnull()函数,是Series和DataFrame对象的方法

df['one'].isnull()
df['one'].notnull()

缺少数据的计算

  • 在求和数据时,NA将被视为0
  • 如果数据全部是NA,那么结果将是NA
df['one'].sum()

清理/填充缺少数据

用标量值替换NaN

df.fillna(0)  # 用0替换NAN, 当然,也可以填充任何其他的值。

根据前面或后面的值填充NAN

方法 动作
pad/fill 根据前面填充
bfill/backfill 根据后面填充
df.fillna(method='pad')
df.fillna(method='backfill')
df.fillna(method='backfill',axis=1)

删除缺少的值

如果只想排除缺少的值,则使用dropna函数和axis参数。 默认情况下,axis = 0,即在行上应用,这意味着如果行内的任何值是NA,那么整个行被排除。

df.dropna()
df.dropna(axis=1)

替换丢失(或)通用值

用标量值替换NAfillna()函数的等效行为。

df.replace({1000:10,2000:60})  # 把1000和2000分别替换为10,60
print(df.replace({np.nan:100000}))

分组(GroupBy)

任何分组(groupby)操作都涉及原始对象的以下操作之一。它们是 -

  • 分割对象
  • 应用一个函数
  • 结合的结果

在许多情况下,我们将数据分成多个集合,并在每个子集上应用一些函数。在应用函数中,可以执行以下操作

  • 聚合 - 计算汇总统计
  • 转换 - 执行一些特定于组的操作
  • 过滤 - 在某些情况下丢弃数据

DataFrame对象所有操作

将数据拆分成组

Pandas对象可以分成任何对象。

  • obj.groupby(‘key’)
  • obj.groupby([‘key1’,’key2’])
  • obj.groupby(key,axis=1)
df.groupby('Team')
<pandas.core.groupby.DataFrameGroupBy object at 0x00000245D60AD518>

查看分组

df.groupby('Team').groups
{
'Devils': Int64Index([2, 3], dtype='int64'), 
'Kings': Int64Index([4, 6, 7], dtype='int64'), 
'Riders': Int64Index([0, 1, 8, 11], dtype='int64'), 
'Royals': Int64Index([9, 10], dtype='int64'), 
'kings': Int64Index([5], dtype='int64')
}

按多列分组

df.groupby(['Team','Year']).groups
{
('Devils', 2014): Int64Index([2], dtype='int64'), 
('Devils', 2015): Int64Index([3], dtype='int64'), 
('Kings', 2014): Int64Index([4], dtype='int64'),
('Kings', 2016): Int64Index([6], dtype='int64'),
('Kings', 2017): Int64Index([7], dtype='int64'), 
('Riders', 2014): Int64Index([0], dtype='int64'), 
('Riders', 2015): Int64Index([1], dtype='int64'), 
('Riders', 2016): Int64Index([8], dtype='int64'), 
('Riders', 2017): Int64Index([11], dtype='int64'),
('Royals', 2014): Int64Index([9], dtype='int64'), 
('Royals', 2015): Int64Index([10], dtype='int64'), 
('kings', 2015): Int64Index([5], dtype='int64')
}

迭代遍历分组

使用groupby对象,可以遍历类似itertools.obj的对象。

grouped = df.groupby('Year')

for name,group in grouped:
    print (name)
    print (group)

执行上面示例代码,得到以下结果 -

2014
   Points  Rank    Team  Year
0     876     1  Riders  2014
2     863     2  Devils  2014
4     741     3   Kings  2014
9     701     4  Royals  2014
2015
    Points  Rank    Team  Year
1      789     2  Riders  2015
3      673     3  Devils  2015
5      812     4   kings  2015
10     804     1  Royals  2015

默认情况下,groupby对象具有与分组名相同的标签名称。

选择一个分组

使用get_group()方法,可以选择一个组。参考以下示例代码 -

grouped = df.groupby('Year')
grouped.get_group(2014)
   Points  Rank    Team  Year
0     876     1  Riders  2014
2     863     2  Devils  2014
4     741     3   Kings  2014
9     701     4  Royals  2014

聚合

聚合函数为每个组返回单个聚合值。当创建了分组(group by)对象,就可以对分组数据执行多个聚合操作。

一个比较常用的是通过聚合或等效的agg方法聚合

grouped = df.groupby('Year')
grouped['Points'].agg(np.mean)
Year
2014    795.25
2015    769.50
2016    725.00
2017    739.00
Name: Points, dtype: float64

另一种查看每个分组的大小的方法是应用size()函数

grouped = df.groupby('Team')
grouped.agg(np.size)
Team                      
Devils       2     2     2
Kings        3     3     3
Riders       4     4     4
Royals       2     2     2
kings        1     1     1

一次应用多个聚合函数

通过分组系列,还可以传递函数的列表或字典来进行聚合,并生成DataFrame作为输出 -

grouped = df.groupby('Team')
agg = grouped['Points'].agg([np.sum, np.mean, np.std])
         sum        mean         std
Team                                
Devils  1536  768.000000  134.350288
Kings   2285  761.666667   24.006943
Riders  3049  762.250000   88.567771
Royals  1505  752.500000   72.831998
kings    812  812.000000         NaN

转换

分组或列上的转换返回索引大小与被分组的索引相同的对象。因此,转换应该返回与组块大小相同的结果。

grouped = df.groupby('Team')
score = lambda x: (x - x.mean()) / x.std()*10
grouped.transform(score)
       Points       Rank       Year
0   12.843272 -15.000000 -11.618950
1    3.020286   5.000000  -3.872983
2    7.071068  -7.071068  -7.071068
3   -7.071068   7.071068   7.071068
4   -8.608621  11.547005 -10.910895
5         NaN        NaN        NaN
6   -2.360428  -5.773503   2.182179
7   10.969049  -5.773503   8.728716
8   -7.705963   5.000000   3.872983
9   -7.071068   7.071068  -7.071068
10   7.071068  -7.071068   7.071068
11  -8.157595   5.000000  11.618950

过滤

过滤根据定义的标准过滤数据并返回数据的子集。filter()函数用于过滤数据。

filter = df.groupby('Team').filter(lambda x: len(x) >= 3)
    Points  Rank    Team  Year
0      876     1  Riders  2014
1      789     2  Riders  2015
4      741     3   Kings  2014
6      756     1   Kings  2016
7      788     1   Kings  2017
8      694     2  Riders  2016
11     690     2  Riders  2017

Pandas合并/连接

Pandas具有功能全面的高性能内存中连接操作,与SQL等关系数据库非常相似。
Pandas提供了一个单独的merge()函数,作为DataFrame对象之间所有标准数据库连接操作的入口

pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,
left_index=False, right_index=False, sort=True)

在这里,有以下几个参数可以使用 -

  • left - 一个DataFrame对象。
  • right - 另一个DataFrame对象。
  • on - 列(名称)连接,必须在左和右DataFrame对象中存在(找到)。
  • left_on - 左侧DataFrame中的列用作键,可以是列名或长度等于DataFrame长度的数组。
  • right_on - 右侧的DataFrame的列作为键,可以是列名或长度等于DataFrame长度的数组。
  • left_index - 如果为True,则使用左侧DataFrame中的索引(行标签)作为其连接键。 在具有MultiIndex(分层)的DataFrame的情况下,级别的数量必须与来自右DataFrame的连接键的数量相匹配。
  • right_index - 与右DataFrame的left_index具有相同的用法。
  • how - 它是left, right, outer以及inner之中的一个,默认为内inner。 下面将介绍每种方法的用法。
  • sort - 按照字典顺序通过连接键对结果DataFrame进行排序。默认为True,设置为False时,在很多情况下大大提高性能。

在一个键上合并两个数据帧

rs = pd.merge(left,right,on='id')

合并多个键上的两个数据框

rs = pd.merge(left,right,on=['id','subject_id'])

合并使用“how”的参数

如果组合键没有出现在左侧或右侧表中,则连接表中的值将为NA

合并方法 SQL等效 描述
left LEFT OUTER JOIN 使用左侧对象的键
right RIGHT OUTER JOIN 使用右侧对象的键
outer FULL OUTER JOIN 使用键的联合
inner INNER JOIN 使用键的交集
rs = pd.merge(left, right, on='subject_id', how='left')
rs = pd.merge(left, right, on='subject_id', how='right')
rs = pd.merge(left, right, how='outer', on='subject_id')
rs = pd.merge(left, right, on='subject_id', how='inner')

Pandas级联

Pandas提供了各种工具(功能),可以轻松地将SeriesDataFramePanel对象组合在一起。

pd.concat(objs,axis=0,join='outer',join_axes=None,
ignore_index=False)

其中,

  • objs - 这是Series,DataFrame或Panel对象的序列或映射。
  • axis - {0,1,...},默认为0,这是连接的轴。
  • join - {'inner', 'outer'},默认inner。如何处理其他轴上的索引。联合的外部和交叉的内部。
  • ignore_index − 布尔值,默认为False。如果指定为True,则不要使用连接轴上的索引值。结果轴将被标记为:0,...,n-1
  • join_axes - 这是Index对象的列表。用于其他(n-1)轴的特定索引,而不是执行内部/外部集逻辑。

连接对象

concat()函数完成了沿轴执行级联操作的所有重要工作。下面代码中,创建不同的对象并进行连接。

import pandas as pd
one = pd.DataFrame({
         'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'],
         'subject_id':['sub1','sub2','sub4','sub6','sub5'],
         'Marks_scored':[98,90,87,69,78]},
         index=[1,2,3,4,5])
two = pd.DataFrame({
         'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'],
         'subject_id':['sub2','sub4','sub3','sub6','sub5'],
         'Marks_scored':[89,80,79,97,88]},
         index=[1,2,3,4,5])
rs = pd.concat([one,two])
print(rs)
   Marks_scored    Name subject_id
1            98    Alex       sub1
2            90     Amy       sub2
3            87   Allen       sub4
4            69   Alice       sub6
5            78  Ayoung       sub5
1            89   Billy       sub2
2            80   Brian       sub4
3            79    Bran       sub3
4            97   Bryce       sub6
5            88   Betty       sub5

假设想把特定的键与每个碎片的DataFrame关联起来。可以通过使用键参数来实现这一点 -

import pandas as pd
one = pd.DataFrame({
         'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'],
         'subject_id':['sub1','sub2','sub4','sub6','sub5'],
         'Marks_scored':[98,90,87,69,78]},
         index=[1,2,3,4,5])
two = pd.DataFrame({
         'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'],
         'subject_id':['sub2','sub4','sub3','sub6','sub5'],
         'Marks_scored':[89,80,79,97,88]},
         index=[1,2,3,4,5])
rs = pd.concat([one,two],keys=['x','y'])
print(rs)
     Marks_scored    Name subject_id
x 1            98    Alex       sub1
  2            90     Amy       sub2
  3            87   Allen       sub4
  4            69   Alice       sub6
  5            78  Ayoung       sub5
y 1            89   Billy       sub2
  2            80   Brian       sub4
  3            79    Bran       sub3
  4            97   Bryce       sub6
  5            88   Betty       sub5

结果的索引是重复的; 每个索引重复。如果想要生成的对象必须遵循自己的索引,请将ignore_index设置为True。参考以下示例代码

import pandas as pd
one = pd.DataFrame({
         'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'],
         'subject_id':['sub1','sub2','sub4','sub6','sub5'],
         'Marks_scored':[98,90,87,69,78]},
         index=[1,2,3,4,5])
two = pd.DataFrame({
         'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'],
         'subject_id':['sub2','sub4','sub3','sub6','sub5'],
         'Marks_scored':[89,80,79,97,88]},
         index=[1,2,3,4,5])
rs = pd.concat([one,two],keys=['x','y'],ignore_index=True)

print(rs)
Python

执行上面示例代码,得到以下结果 -

   Marks_scored    Name subject_id
0            98    Alex       sub1
1            90     Amy       sub2
2            87   Allen       sub4
3            69   Alice       sub6
4            78  Ayoung       sub5
5            89   Billy       sub2
6            80   Brian       sub4
7            79    Bran       sub3
8            97   Bryce       sub6
9            88   Betty       sub5

观察,索引完全改变,键也被覆盖。如果需要沿axis=1添加两个对象,则会添加新列。

import pandas as pd
one = pd.DataFrame({
         'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'],
         'subject_id':['sub1','sub2','sub4','sub6','sub5'],
         'Marks_scored':[98,90,87,69,78]},
         index=[1,2,3,4,5])
two = pd.DataFrame({
         'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'],
         'subject_id':['sub2','sub4','sub3','sub6','sub5'],
         'Marks_scored':[89,80,79,97,88]},
         index=[1,2,3,4,5])
rs = pd.concat([one,two],axis=1)
print(rs)

执行上面示例代码,得到以下结果 -

   Marks_scored    Name subject_id  Marks_scored   Name subject_id
1            98    Alex       sub1            89  Billy       sub2
2            90     Amy       sub2            80  Brian       sub4
3            87   Allen       sub4            79   Bran       sub3
4            69   Alice       sub6            97  Bryce       sub6
5            78  Ayoung       sub5            88  Betty       sub5

使用附加连接

连接的一个有用的快捷方式是在Series和DataFrame实例的append方法。这些方法实际上早于concat()方法。 它们沿axis=0连接,即索引

import pandas as pd
one = pd.DataFrame({
         'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'],
         'subject_id':['sub1','sub2','sub4','sub6','sub5'],
         'Marks_scored':[98,90,87,69,78]},
         index=[1,2,3,4,5])
two = pd.DataFrame({
         'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'],
         'subject_id':['sub2','sub4','sub3','sub6','sub5'],
         'Marks_scored':[89,80,79,97,88]},
         index=[1,2,3,4,5])
rs = one.append(two)
print(rs)
   Marks_scored    Name subject_id
1            98    Alex       sub1
2            90     Amy       sub2
3            87   Allen       sub4
4            69   Alice       sub6
5            78  Ayoung       sub5
1            89   Billy       sub2
2            80   Brian       sub4
3            79    Bran       sub3
4            97   Bryce       sub6
5            88   Betty       sub5

append()函数也可以带多个对象

import pandas as pd

one = pd.DataFrame({
         'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'],
         'subject_id':['sub1','sub2','sub4','sub6','sub5'],
         'Marks_scored':[98,90,87,69,78]},
         index=[1,2,3,4,5])

two = pd.DataFrame({
         'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'],
         'subject_id':['sub2','sub4','sub3','sub6','sub5'],
         'Marks_scored':[89,80,79,97,88]},
         index=[1,2,3,4,5])
rs = one.append([two,one,two])
print(rs)

执行上面示例代码,得到以下结果 -

   Marks_scored    Name subject_id
1            98    Alex       sub1
2            90     Amy       sub2
3            87   Allen       sub4
4            69   Alice       sub6
5            78  Ayoung       sub5
1            89   Billy       sub2
2            80   Brian       sub4
3            79    Bran       sub3
4            97   Bryce       sub6
5            88   Betty       sub5
1            98    Alex       sub1
2            90     Amy       sub2
3            87   Allen       sub4
4            69   Alice       sub6
5            78  Ayoung       sub5
1            89   Billy       sub2
2            80   Brian       sub4
3            79    Bran       sub3
4            97   Bryce       sub6
5            88   Betty       sub5

时间序列

Pandas为时间序列数据的工作时间提供了一个强大的工具,尤其是在金融领域。在处理时间序列数据时,我们经常遇到以下情况

  • 生成时间序列
  • 将时间序列转换为不同的频率

Pandas提供了一个相对紧凑和自包含的工具来执行上述任务。

获取当前时间(pd将移除该方法,应该使用datetime)

pd.datetime.now()
2017-11-03 02:17:45.997992

创建一个时间戳

时间戳数据是时间序列数据的最基本类型,它将数值与时间点相关联。 对于Pandas对象来说,意味着使用时间点。

time = pd.Timestamp('2018-11-01')
2018-11-01 00:00:00

也可以转换整数或浮动时期。这些的默认单位是纳秒。

time = pd.Timestamp(1588686880,unit='s')
2020-05-05 13:54:40

创建一个时间范围

# 默认频率为 D,time 是取time部分
time = pd.date_range("12:00", "23:59", freq="30min").time  
[datetime.time(12, 0) datetime.time(12, 30) datetime.time(13, 0)
 datetime.time(13, 30) datetime.time(14, 0) datetime.time(14, 30)
 datetime.time(15, 0) datetime.time(15, 30) datetime.time(16, 0)
 datetime.time(16, 30) datetime.time(17, 0) datetime.time(17, 30)
 datetime.time(18, 0) datetime.time(18, 30) datetime.time(19, 0)
 datetime.time(19, 30) datetime.time(20, 0) datetime.time(20, 30)
 datetime.time(21, 0) datetime.time(21, 30) datetime.time(22, 0)
 datetime.time(22, 30) datetime.time(23, 0) datetime.time(23, 30)]

改变时间的频率

time = pd.date_range("12:00", "23:59", freq="H").time
[datetime.time(12, 0) datetime.time(13, 0) datetime.time(14, 0)
 datetime.time(15, 0) datetime.time(16, 0) datetime.time(17, 0)
 datetime.time(18, 0) datetime.time(19, 0) datetime.time(20, 0)
 datetime.time(21, 0) datetime.time(22, 0) datetime.time(23, 0)]

转换为时间戳

要转换类似日期的对象(例如字符串,时代或混合)的序列或类似列表的对象,可以使用to_datetime函数。当传递时将返回一个Series(具有相同的索引),而类似列表被转换为DatetimeIndex。 看看下面的例子 -

time = pd.to_datetime(pd.Series(['Jul 31, 2009','2019-10-10', None]))
0   2009-07-31
1   2019-10-10
2          NaT
dtype: datetime64[ns]

NaT表示不是一个时间的值(相当于NaN)

time = pd.to_datetime(['2009/11/23', '2019.12.31', None])
DatetimeIndex(['2009-11-23', '2019-12-31', 'NaT'], dtype='datetime64[ns]', freq=None)

Pandas日期功能

日期功能扩展了时间序列,在财务数据分析中起主要作用。在处理日期数据的同时,我们经常会遇到以下情况

  • 生成日期序列
  • 将日期序列转换为不同的频率

创建一个日期范围

通过指定周期和频率,使用date.range()函数就可以创建日期序列。 默认情况下,范围的频率是天。

datelist = pd.date_range('2020/11/21', periods=5)
DatetimeIndex(['2020-11-21', '2020-11-22', '2020-11-23', '2020-11-24',
               '2020-11-25'],
              dtype='datetime64[ns]', freq='D')

更改日期频率

datelist = pd.date_range('2020/11/21', periods=5,freq='M')
DatetimeIndex(['2020-11-30', '2020-12-31', '2021-01-31', '2021-02-28',
               '2021-03-31'],
              dtype='datetime64[ns]', freq='M')

bdate_range()函数

bdate_range()用来表示商业日期范围,不同于date_range(),它不包括星期六和星期天。

datelist = pd.bdate_range('2011/11/03', periods=7)

date_rangebdate_range这样的便利函数利用了各种频率别名。date_range的默认频率是日历中的自然日,而bdate_range的默认频率是工作日。

start = pd.datetime(2017, 11, 1)
end = pd.datetime(2017, 11, 5)
dates = pd.date_range(start, end)
DatetimeIndex(['2017-11-01', '2017-11-02', '2017-11-03', '2017-11-04',
               '2017-11-05'],
              dtype='datetime64[ns]', freq='D')

偏移别名

大量的字符串别名被赋予常用的时间序列频率。我们把这些别名称为偏移别名。

别名 描述说明
B 工作日频率
BQS 商务季度开始频率
D 日历/自然日频率
A 年度(年)结束频率
W 每周频率
BA 商务年底结束
M 月结束频率
BAS 商务年度开始频率
SM 半月结束频率
BH 商务时间频率
SM 半月结束频率
BH 商务时间频率
BM 商务月结束频率
H 小时频率
MS 月起始频率
T, min 分钟的频率
SMS SMS半开始频率
S 秒频率
BMS 商务月开始频率
L, ms 毫秒
Q 季度结束频率
U, us 微秒
BQ 商务季度结束频率
N 纳秒
BQ 商务季度结束频率
QS 季度开始频率

Pandas时间差(Timedelta)

时间差(Timedelta)是时间上的差异,以不同的单位来表示。例如:日,小时,分钟,秒。它们可以是正值,也可以是负值。

字符串

通过传递字符串,可以创建一个timedelta对象。参考以下示例代码 -

timediff = pd.Timedelta('2 days 2 hours 15 minutes 30 seconds')
2 days 02:15:30

整数

通过传递一个整数值与指定单位,这样的一个参数也可以用来创建Timedelta对象。

timediff = pd.Timedelta(6,unit='h')
0 days 06:00:00

数据偏移

例如 - 周,天,小时,分钟,秒,毫秒,微秒,纳秒的数据偏移也可用于构建。

timediff = pd.Timedelta(days=2)
2 days 00:00:00

运算操作

可以在Series/DataFrames上执行运算操作,并通过在datetime64 [ns]系列或在时间戳上减法操作来构造timedelta64 [ns]系列。参考以下示例代码 -

s = pd.Series(pd.date_range('2012-1-1', periods=3, freq='D'))
td = pd.Series([ pd.Timedelta(days=i) for i in range(3) ])
df = pd.DataFrame(dict(A = s, B = td))
           A      B
0 2012-01-01 0 days
1 2012-01-02 1 days
2 2012-01-03 2 days

相加操作

df['C']=df['A']+df['B']
df.C = df.A-df.B  # 报错,不允许 点 . 
           A      B          C
0 2018-01-01 0 days 2018-01-01
1 2018-01-02 1 days 2018-01-03
2 2018-01-03 2 days 2018-01-05

相减操作

df['D']=df['C']-df['B']
           A      B          C          D
0 2018-01-01 0 days 2018-01-01 2018-01-01
1 2018-01-02 1 days 2018-01-03 2018-01-02
2 2018-01-03 2 days 2018-01-05 2018-01-03

Pandas分类数据

通常实时的数据包括重复的文本列。例如:性别,国家和代码等特征总是重复的。这些是分类数据的例子。

分类变量只能采用有限的数量,而且通常是固定的数量。除了固定长度,分类数据可能有顺序,但不能执行数字操作。 分类是Pandas数据类型。

分类数据类型在以下情况下非常有用

  • 一个字符串变量,只包含几个不同的值。将这样的字符串变量转换为分类变量将会节省一些内存。
  • 变量的词汇顺序与逻辑顺序("one""two""three")不同。 通过转换为分类并指定类别上的顺序,排序和最小/最大将使用逻辑顺序,而不是词法顺序。
  • 作为其他python库的一个信号,这个列应该被当作一个分类变量(例如,使用合适的统计方法或plot类型)。

对象创建

分类对象可以通过多种方式创建。类别/分类

通过在pandas对象创建中将dtype指定为“category”

s = pd.Series(["a","b","c","a"], dtype="category")
0    a
1    b
2    c
3    a
dtype: category
Categories (3, object): [a, b, c]

传递给系列对象的元素数量是四个,但类别只有三个。观察相同的输出类别。

pd.Categorical

使用标准Pandas分类构造函数,我们可以创建一个类别对象。语法如下 -

pandas.Categorical(values, categories, ordered)
cat = pd.Categorical(['a', 'b', 'c', 'a', 'b', 'c'])
[a, b, c, a, b, c]
Categories (3, object): [a, b, c]
cat = cat=pd.Categorical(['a','b','c','a','b','c','d'], ['c', 'b', 'a'])
[a, b, c, a, b, c, NaN]
Categories (3, object): [c, b, a]

这里,第二个参数表示类别。因此,在类别中不存在的任何值将被视为NaN

cat = cat=pd.Categorical(['a','b','c','a','b','c','d'], ['c', 'b', 'a'],ordered=True)
[a, b, c, a, b, c, NaN]
Categories (3, object): [c < b < a]

从逻辑上讲,排序(ordered)意味着,a大于bb大于c

描述

使用分类数据上的.describe()命令,可以得到与类型字符串的Series或DataFrame类似的输出。

cat = pd.Categorical(["a", "c", "c", np.nan], categories=["b", "a", "c"])
df = pd.DataFrame({"cat":cat, "s":["a", "c", "c", np.nan]})
print (df.describe())
print ("=============================")
print (df["cat"].describe())
       cat  s
count    3  3
unique   2  2
top      c  c
freq     2  2
=============================
count     3
unique    2
top       c
freq      2
Name: cat, dtype: object

获取类别的属性

obj.cat.categories命令用于获取对象的类别。

s = pd.Categorical(["a", "c", "c", np.nan], categories=["b", "a", "c"])
s.categories
Index(['b', 'a', 'c'], dtype='object')

obj.ordered命令用于获取对象的顺序。

cat = pd.Categorical(["a", "c", "c", np.nan], categories=["b", "a", "c"])
cat.ordered
False

该函数返回结果为:False,因为这里没有指定任何顺序。

重命名类别

重命名类别是通过将新值分配给series.cat.categories属性来完成的。

s = pd.Series(["a","b","c","a"], dtype="category")
s.cat.categories = ["Group %s" % g for g in s.cat.categories]
s.cat.categories

s = pd.Categorical(['a','b','c','c'])
s.categories = ['aaa %s'%g for g in s.categories]
s.categories
Index(['Group a', 'Group b', 'Group c'], dtype='object')

初始类别[a,b,c]由对象的s.cat.categories属性更新。

附加新类别
使用Categorical.add.categories()方法,可以追加新的类别。

s = pd.Series(["a","b","c","a"], dtype="category")
s = s.cat.add_categories([4])
s.cat.categories
Index(['a', 'b', 'c', 4], dtype='object')

删除类别
使用Categorical.remove_categories()方法,可以删除不需要的类别。

s.cat.remove_categories("a")

执行上面示例代码,得到以下结果 -

Original object:
0    a
1    b
2    c
3    a
dtype: category
Categories (3, object): [a, b, c]
=====================================
After removal:
0    NaN
1      b
2      c
3    NaN
dtype: category
Categories (2, object): [b, c]
Shell

分类数据的比较

在三种情况下可以将分类数据与其他对象进行比较

  • 将等号(==!=)与类别数据相同长度的类似列表的对象(列表,系列,数组…)进行比较。
  • ordered==True和类别是相同时,所有比较(==!=>>=<,和<=)分类数据到另一个分类系列。
  • 将分类数据与标量进行比较。
cat = pd.Series([1,2,3]).astype("category", categories=[1,2,3], ordered=True)
cat1 = pd.Series([2,2,2]).astype("category", categories=[1,2,3], ordered=True)
print (cat>cat1)
0    False
1    False
2     True
dtype: bool

与分类比较:

类不同,不能比较:

Categoricals can only be compared if 'categories' are the same.

大小未排序,只能比较相不相同,不能比:

Unordered Categoricals can only compare equality or not

与列表比较:

长度相同:

cat==[1,2,3]

与标量比较:

cat==5 # 可以

cat>5 # 报错

Cannot compare a Categorical for op gt with a scalar, which is not a category.

Pandas可视化

基本绘图:绘图

Series和DataFrame上的这个功能只是使用matplotlib库的plot()方法的简单包装实现。

df = pd.DataFrame(np.random.randn(10,4),index=pd.date_range('2018/12/18',
   periods=10), columns=list('ABCD'))
df.plot()

执行上面示例代码,得到以下结果 -

img

如果索引由日期组成,则调用gct().autofmt_xdate()来格式化x轴,如上图所示。

我们可以使用xy关键字绘制一列与另一列。

绘图方法允许除默认线图之外的少数绘图样式。 这些方法可以作为plot()kind关键字参数提供。这些包括

  • barbarh为条形
  • hist为直方图
  • boxplot为盒型图
  • area为“面积”
  • scatter为散点图

条形图

df = pd.DataFrame(np.random.rand(10,4),columns=['a','b','c','d'])
df.plot.bar()

img

要生成一个堆积条形图,通过指定:stacked=True

df = pd.DataFrame(np.random.rand(10,4),columns=['a','b','c','d'])
df.plot.bar(stacked=True)

img

要获得水平条形图,使用barh()方法 -

df = pd.DataFrame(np.random.rand(10,4),columns=['a','b','c','d'])
df.plot.barh(stacked=True)

执行上面示例代码,得到以下结果 -

img

直方图

可以使用plot.hist()方法绘制直方图。我们可以指定bins的数量值。

df = pd.DataFrame({'a':np.random.randn(1000)+1,'b':np.random.randn(1000),'c':
np.random.randn(1000) - 1}, columns=['a', 'b', 'c'])
df.plot.hist(bins=20)

img

要为每列绘制不同的直方图,请使用以下代码 -

df=pd.DataFrame({'a':np.random.randn(1000)+1,'b':np.random.randn(1000),'c':
np.random.randn(1000) - 1}, columns=['a', 'b', 'c'])
df.hist(bins=20)

img

箱形图

Boxplot可以绘制调用Series.box.plot()DataFrame.box.plot()DataFrame.boxplot()来可视化每列中值的分布。

例如,这里是一个箱形图,表示对[0,1)上的统一随机变量的10次观察的五次试验。

df = pd.DataFrame(np.random.rand(10, 5), columns=['A', 'B', 'C', 'D', 'E'])
df.plot.box()

img

区域块图形

可以使用Series.plot.area()DataFrame.plot.area()方法创建区域图形。

df = pd.DataFrame(np.random.rand(10, 4), columns=['a', 'b', 'c', 'd'])
df.plot.area()

执行上面示例代码,得到以下结果 -

img

散点图形

可以使用DataFrame.plot.scatter()方法创建散点图。

df = pd.DataFrame(np.random.rand(50, 4), columns=['a', 'b', 'c', 'd'])
df.plot.scatter(x='a', y='b')

img

饼状图

饼状图可以使用DataFrame.plot.pie()方法创建。

df = pd.DataFrame(3 * np.random.rand(4), index=['a', 'b', 'c', 'd'], columns=['x'])
df.plot.pie(subplots=True)

img

Pandas IO工具

Pandas I/O API是一套像pd.read_csv()一样返回Pandas对象的顶级读取器函数。

读取文本文件(或平面文件)的两个主要功能是read_csv()read_table()。它们都使用相同的解析代码来智能地将表格数据转换为DataFrame对象

形式1

pandas.read_csv(filepath_or_buffer, sep=',', delimiter=None, header='infer',
names=None, index_col=None, usecols=None)

形式2

pandas.read_csv(filepath_or_buffer, sep='	', delimiter=None, header='infer',
names=None, index_col=None, usecols=None)

以下是csv文件数据的内容 -

S.No,Name,Age,City,Salary
1,Tom,28,Toronto,20000
2,Lee,32,HongKong,3000
3,Steven,43,Bay Area,8300
4,Ram,38,Hyderabad,3900

read.csv

read.csv从csv文件中读取数据并创建一个DataFrame对象。

import pandas as pd
df=pd.read_csv("temp.csv")

执行上面示例代码,得到以下结果 -

   S.No    Name  Age       City  Salary
0     1     Tom   28    Toronto   20000
1     2     Lee   32   HongKong    3000
2     3  Steven   43   Bay Area    8300
3     4     Ram   38  Hyderabad    3900

自定义索引

可以指定csv文件中的一列来使用index_col定制索引。

df=pd.read_csv("temp.csv",index_col=['S.No'])

执行上面示例代码,得到以下结果 -

        Name  Age       City  Salary
S.No                                
1        Tom   28    Toronto   20000
2        Lee   32   HongKong    3000
3     Steven   43   Bay Area    8300
4        Ram   38  Hyderabad    3900

转换器
dtype的列可以作为字典传递。转换数据类型。

df = pd.read_csv("temp.csv", dtype={'Salary': np.float64})
print (df.dtypes)
S.No        int64
Name       object
Age         int64
City       object
Salary    float64
dtype: object

默认情况下,Salary列的dtypeint,但结果显示为float,因为我们明确地转换了类型。

  S.No   Name   Age      City    Salary
0   1     Tom   28    Toronto   20000.0
1   2     Lee   32   HongKong    3000.0
2   3  Steven   43   Bay Area    8300.0
3   4     Ram   38  Hyderabad    3900.0

header_names
使用names参数指定标题的名称。

df=pd.read_csv("temp.csv", names=['a', 'b', 'c','d','e'])
      a       b    c          d       e
0  S.No    Name  Age       City  Salary
1     1     Tom   28    Toronto   20000
2     2     Lee   32   HongKong    3000
3     3  Steven   43   Bay Area    8300
4     4     Ram   38  Hyderabad    3900

观察可以看到,标题名称附加了自定义名称,但文件中的标题还没有被消除。 现在,使用header参数来删除它。

如果标题不是第一行,则将行号传递给标题。这将跳过前面的行。

df=pd.read_csv("temp.csv",names=['a','b','c','d','e'],header=0)
   a       b   c          d      e
0  1     Tom  28    Toronto  20000
1  2     Lee  32   HongKong   3000
2  3  Steven  43   Bay Area   8300
3  4     Ram  38  Hyderabad   3900

skiprows

skiprows跳过指定的行数。

df=pd.read_csv("temp.csv", skiprows=2)
   2     Lee  32   HongKong  3000
0  3  Steven  43   Bay Area  8300
1  4     Ram  38  Hyderabad  3900

Pandas稀疏数据

当任何匹配特定值的数据(NaN/缺失值,尽管可以选择任何值)被省略时,稀疏对象被“压缩”。 一个特殊的SparseIndex对象跟踪数据被“稀疏”的地方。 这将在一个例子中更有意义。 所有的标准Pandas数据结构都应用了to_sparse方法

ts = pd.Series(np.random.randn(10))
ts[2:-2] = np.nan
sts = ts.to_sparse()
0   -0.391926
1   -1.774880
2         NaN 
3         NaN
4         NaN
5         NaN
6         NaN
7         NaN
8    0.642988
9   -0.373698
dtype: float64
BlockIndex
Block locations: array([0, 8])
Block lengths: array([2, 2])

为了内存效率的原因,所以需要稀疏对象的存在。

现在假设有一个大的NA DataFrame并执行下面的代码 -

df = pd.DataFrame(np.random.randn(10000, 4))
df.ix[:9998] = np.nan
sdf = df.to_sparse()
print (sdf.density)

执行上面示例代码,得到以下结果 -

0.0001
Shell

通过调用to_dense可以将任何稀疏对象转换回标准密集形式 -

import pandas as pd
import numpy as np
ts = pd.Series(np.random.randn(10))
ts[2:-2] = np.nan
sts = ts.to_sparse()
print (sts.to_dense())
Python

执行上面示例代码,得到以下结果 -

0   -0.275846
1    1.172722
2         NaN
3         NaN
4         NaN
5         NaN
6         NaN
7         NaN
8   -0.612009
9   -1.413996
dtype: float64
Shell

稀疏Dtypes

稀疏数据应该具有与其密集表示相同的dtype。 目前,支持float64int64booldtypes。 取决于原始的dtypefill_value默认值的更改 -

  • float64np.nan
  • int640
  • boolFalse

执行下面的代码来理解相同的内容 -

import pandas as pd
import numpy as np

s = pd.Series([1, np.nan, np.nan])
print (s)
print ("=============================")
s.to_sparse()
print (s)
Python

执行上面示例代码,得到以下结果 -

0    1.0
1    NaN
2    NaN
dtype: float64
=============================
0    1.0
1    NaN
2    NaN
dtype: float64

Pandas注意事项&窍门

警告和疑难意味着一个看不见的问题。在使用Pandas过程中,需要特别注意的地方。

与Pandas一起使用If/Truth语句

当尝试将某些东西转换成布尔值时,Pandas遵循了一个错误的惯例。 这种情况发生在使用布尔运算的。 目前还不清楚结果是什么。 如果它是真的,因为它不是zerolength? 错误,因为有错误的值? 目前还不清楚,Pandas提出了一个ValueError

import pandas as pd

if pd.Series([False, True, False]):
    print ('I am True')
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

if条件,它不清楚如何处理它。错误提示是否使用None或任何这些。

import pandas as pd
if pd.Series([False, True, False]).any():  # 任何True
    print("I am any")

要在布尔上下文中评估单元素Pandas对象,请使用方法.bool()

import pandas as pd
print (pd.Series([True]).bool())  # 只能有一个值,结果:True

按位布尔值

按位布尔运算符(如==!=)将返回一个布尔系列,这几乎总是需要的。

import pandas as pd

s = pd.Series(range(5))
print (s==4)

执行上面示例代码,得到以下结果 -

0    False
1    False
2    False
3    False
4     True
dtype: bool

isin操作符

这将返回一个布尔序列,显示系列中的每个元素是否完全包含在传递的值序列中。

import pandas as pd

s = pd.Series(list('abc'))
s = s.isin(['a', 'c', 'e'])
print (s)
0     True
1    False
2     True
dtype: bool

重构索引与ix陷阱

许多用户会发现自己使用ix索引功能作为从Pandas对象中选择数据的简洁方法

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(6, 4), columns=['one', 'two', 'three',
'four'],index=list('abcdef'))

print (df)
print ("=============================================")
print (df.ix[['b', 'c', 'e']])

执行上面示例代码,得到以下结果 -

        one       two     three      four
a -1.174632  0.951047 -0.177007  1.036567
b -0.806324 -0.562209  1.081449 -1.047623
c  0.107607  0.778843 -0.063531 -1.073552
d -0.277602 -0.962720  1.381249  0.868656
e  0.576266  0.986949  0.433569  0.539558
f -0.708917 -0.583124 -0.686753 -2.338110
=============================================
        one       two     three      four
b -0.806324 -0.562209  1.081449 -1.047623
c  0.107607  0.778843 -0.063531 -1.073552
e  0.576266  0.986949  0.433569  0.539558

这当然在这种情况下完全等同于使用reindex方法

import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(6, 4), columns=['one', 'two', 'three',
'four'],index=list('abcdef'))
print (df)
print("=============================================")
print (df.reindex(['b', 'c', 'e']))

执行上面示例代码,得到以下结果 -

        one       two     three      four
a -1.754084 -1.423820 -0.152234 -1.475104
b  1.508714 -0.216916 -0.184434 -2.117229
c -0.409298 -0.224142  0.308175 -0.681308
d  0.938517 -1.626353 -0.180770 -0.470252
e  0.718043 -0.730215 -0.716810  0.546039
f  2.313001  0.371286  0.359952  2.126530
=============================================
        one       two     three      four
b  1.508714 -0.216916 -0.184434 -2.117229
c -0.409298 -0.224142  0.308175 -0.681308
e  0.718043 -0.730215 -0.716810  0.546039

有人可能会得出这样的结论,ixreindex是基于这个100%的等价物。 除了整数索引的情况,它是true。例如,上述操作可选地表示为 -

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(6, 4), columns=['one', 'two', 'three',
'four'],index=list('abcdef'))

print (df)
print("=====================================")
print (df.ix[[1, 2, 4]])
print("=====================================")
print (df.reindex([1, 2, 4]))
        one       two     three      four
a  1.017408  0.594357 -0.760587  1.001547
b -1.480067  1.524270  0.455070  1.886959
c -0.136238 -0.165867 -0.589767 -1.078473
d  0.670576  1.600312  0.219578 -1.121352
e -0.224181  0.958156  0.013055 -0.013652
f  1.576155 -0.185003 -0.527204 -0.336275
=====================================
        one       two     three      four
b -1.480067  1.524270  0.455070  1.886959
c -0.136238 -0.165867 -0.589767 -1.078473
e -0.224181  0.958156  0.013055 -0.013652
=====================================
   one  two  three  four
1  NaN  NaN    NaN   NaN
2  NaN  NaN    NaN   NaN
4  NaN  NaN    NaN   NaN
Shell

重要的是要记住,reindex只是严格的标签索引。这可能会导致一些潜在的令人惊讶的结果,例如索引包含整数和字符串的病态情况。

Pandas与SQL比较

由于许多潜在的Pandas用户对SQL有一定的了解,因此本文章旨在提供一些如何使用Pandas执行各种SQL操作的示例。

import pandas as pd
url = 'tips.csv'
tips=pd.read_csv(url)
print (tips.head())

文件:tips.csv -

total_bill,tip,sex,smoker,day,time,size
0,16.99,1.01,Female,No,Sun,Dinner,2
1,10.34,1.66,Male,No,Sun,Dinner,3
2,21.01,3.50,Male,No,Sun,Dinner,3
3,23.68,3.31,Male,No,Sun,Dinner,2
4,24.59,3.61,Female,No,Sun,Dinner,4

执行上面示例代码,得到以下结果 -

   total_bill   tip     sex smoker  day    time  size
0       16.99  1.01  Female     No  Sun  Dinner     2
1       10.34  1.66    Male     No  Sun  Dinner     3
2       21.01  3.50    Male     No  Sun  Dinner     3
3       23.68  3.31    Male     No  Sun  Dinner     2
4       24.59  3.61  Female     No  Sun  Dinner     4

选择(Select)

在SQL中,选择是使用逗号分隔的列列表(或选择所有列)来完成的,例如 -

SELECT total_bill, tip, smoker, time
FROM tips
LIMIT 5;
SQL

Pandas中,列的选择是通过传递列名到DataFrame -

tips[['total_bill', 'tip', 'smoker', 'time']].head(5)
Python

下面来看看完整的程序 -

import pandas as pd

url = 'tips.csv'

tips=pd.read_csv(url)
rs = tips[['total_bill', 'tip', 'smoker', 'time']].head(5)
print(rs)

执行上面示例代码,得到以下结果 -

   total_bill   tip smoker    time
0       16.99  1.01     No  Dinner
1       10.34  1.66     No  Dinner
2       21.01  3.50     No  Dinner
3       23.68  3.31     No  Dinner
4       24.59  3.61     No  Dinner

调用没有列名称列表的DataFrame将显示所有列(类似于SQL的*)。

WHERE条件

SELECT * FROM tips WHERE time = 'Dinner' LIMIT 5;
SQL

数据帧可以通过多种方式进行过滤; 最直观的是使用布尔索引。

tips[tips['time'] == 'Dinner'].head(5)
Python

下面来看看完整的程序 -

import pandas as pd

url = 'tips.csv'

tips=pd.read_csv(url)
rs = tips[tips['time'] == 'Dinner'].head(5)
print(rs)

执行上面示例代码,得到以下结果 -

   total_bill   tip     sex smoker  day    time  size
0       16.99  1.01  Female     No  Sun  Dinner     2
1       10.34  1.66    Male     No  Sun  Dinner     3
2       21.01  3.50    Male     No  Sun  Dinner     3
3       23.68  3.31    Male     No  Sun  Dinner     2
4       24.59  3.61  Female     No  Sun  Dinner     4

上述语句将一系列True/False对象传递给DataFrame,并将所有行返回True

通过GroupBy分组

此操作将获取整个数据集中每个组的记录数。 例如,一个查询提取性别的数量(即,按性别分组) -

SELECT sex, count(*)
FROM tips
GROUP BY sex;
SQL

Pandas中的等值语句将是 -

tips.groupby('sex').size()

下面来看看完整的程序 -

import pandas as pd

url = 'tips.csv'

tips=pd.read_csv(url)
rs = tips.groupby('sex').size()
print(rs)

执行上面示例代码,得到以下结果 -

sex
Female    2
Male      3
dtype: int64

前N行

SQL(MySQL数据库)使用LIMIT返回前n行 -

SELECT * FROM tips
LIMIT 5 ;

Pandas中的等值语句将是 -

tips.head(5)

下面来看看完整的程序 -

import pandas as pd

url = 'tips.csv'

tips=pd.read_csv(url)
rs = tips[['smoker', 'day', 'time']].head(5)
print(rs)

执行上面示例代码,得到以下结果 -

  smoker  day    time
0     No  Sun  Dinner
1     No  Sun  Dinner
2     No  Sun  Dinner
3     No  Sun  Dinner
4     No  Sun  Dinner

这些是比较的几个基本操作,在前几章的Pandas库中学到的。

原文地址:https://www.cnblogs.com/pythonwl/p/14516067.html