Pandas处理以下三个数据结构 ,这些数据结构构建在Numpy数组之上,这意味着它们很快。
- 系列(
Series
) - 数据帧(
DataFrame
) - 面板(
Panel
)
较高维数据结构是其较低维数据结构的容器。 DataFrame
是Series
的容器,Panel
是DataFrame
的容器。
数据结构 | 维数 | 描述 |
---|---|---|
系列(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 |
数据,如:ndarray ,list ,constants |
|
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
可以看到,列A
,B
,C
和D
自动标签完成。E
也在一样。其余的属性为了简洁而被截短。
//原文出自【易百教程】,商业转载请联系作者获得授权,非商业转载请保留原文链接:https://www.yiibai.com/pandas/python_pandas_series.html
DataFrame 操作
pandas.DataFrame( data, index, columns, dtype, copy)
参数 | 描述 | |
---|---|---|
data |
数据,如:ndarray ,series ,map ,list ,dict ,constant 和另一个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 |
数据采取各种形式,如:ndarray ,series ,map ,lists ,dict ,constant 和另一个数据帧(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()
方法沿DataFrame
或Panel
的轴应用任意函数。 默认情况下,操作按列执行,将每列列为数组。
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
对象之间的基本迭代的行为取决于类型。当迭代一个系列时,它被视为数组式,基本迭代产生这些值。其他数据结构,如:DataFrame
和Panel
,遵循类似惯例迭代对象的键。
简而言之,基本迭代(对于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
是行索引,col1
,col2
,col3
是列索引。
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()
提供了:mergeesort
,heapsort
和quicksort
中选择算法的一个配置。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
注 - 观察第一个语句中
a
和b
列之间的cov
结果值,与由DataFrame上的cov
返回的值相同。
相关性
相关性显示了任何两个数值(系列)之间的线性关系。有多种方法来计算pearson
(默认),spearman
和kendall
之间的相关性。
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
),前两个元素有空值,第三个元素的值将是n
,n-1
和n-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()
可应用于系列数据。指定com
,span
,halflife
参数,并在其上应用适当的统计函数。它以指数形式分配权重。
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的缺失值(如NA
或NaN
)。
检测缺失值
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)
替换丢失(或)通用值
用标量值替换NA
是fillna()
函数的等效行为。
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提供了各种工具(功能),可以轻松地将Series
,DataFrame
和Panel
对象组合在一起。
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_range
和bdate_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
大于b
,b
大于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()
执行上面示例代码,得到以下结果 -
如果索引由日期组成,则调用gct().autofmt_xdate()
来格式化x
轴,如上图所示。
我们可以使用x
和y
关键字绘制一列与另一列。
绘图方法允许除默认线图之外的少数绘图样式。 这些方法可以作为plot()
的kind
关键字参数提供。这些包括
bar
或barh
为条形hist
为直方图boxplot
为盒型图area
为“面积”scatter
为散点图
条形图
df = pd.DataFrame(np.random.rand(10,4),columns=['a','b','c','d'])
df.plot.bar()
要生成一个堆积条形图,通过指定:stacked=True
df = pd.DataFrame(np.random.rand(10,4),columns=['a','b','c','d'])
df.plot.bar(stacked=True)
要获得水平条形图,使用barh()
方法 -
df = pd.DataFrame(np.random.rand(10,4),columns=['a','b','c','d'])
df.plot.barh(stacked=True)
执行上面示例代码,得到以下结果 -
直方图
可以使用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)
要为每列绘制不同的直方图,请使用以下代码 -
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)
箱形图
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()
区域块图形
可以使用Series.plot.area()
或DataFrame.plot.area()
方法创建区域图形。
df = pd.DataFrame(np.random.rand(10, 4), columns=['a', 'b', 'c', 'd'])
df.plot.area()
执行上面示例代码,得到以下结果 -
散点图形
可以使用DataFrame.plot.scatter()
方法创建散点图。
df = pd.DataFrame(np.random.rand(50, 4), columns=['a', 'b', 'c', 'd'])
df.plot.scatter(x='a', y='b')
饼状图
饼状图可以使用DataFrame.plot.pie()
方法创建。
df = pd.DataFrame(3 * np.random.rand(4), index=['a', 'b', 'c', 'd'], columns=['x'])
df.plot.pie(subplots=True)
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列的dtype
是int
,但结果显示为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。 目前,支持float64
,int64
和booldtypes
。 取决于原始的dtype
,fill_value
默认值的更改 -
float64
−np.nan
int64
−0
bool
−False
执行下面的代码来理解相同的内容 -
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
有人可能会得出这样的结论,ix
和reindex
是基于这个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库中学到的。