1. Pandas数据结构
Series
是一种一维的数组型对象,它包含了一个值序列,并且包含了数据标签,称为索引。
1.1 Series
obj = pd.Series([4, 7, -5, 3])
obj
0 4
1 7
2 -5
3 3
dtype: int64
获取Series对象的值和索引
obj.values
array([4, 7, -5, 3])
obj.index
RangeIndex(start=0, stop=4, step=1)
创建一个索引序列,用标签标识每个数据点:
obj2 = pd.Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c'])
obj2
d 4
b 7
a -5
c 3
dtype: int64
obj2.index
Index(['d', 'b', 'a', 'c'], dtype='object')
使用标签进行索引:
obj2['a']
-5
obj2['d'] = 6
// 下面的['c', 'a', 'd']表示的是索引列表
obj2[['c', 'a', 'd']]
c 3
a -5
b 6
dtype: int64
obj2[obj2 > 0]
d 6
b 7
c 3
dtype: int64
obj2 * 2
d 12
b 14
a -10
c 6
dtype: int64
np.exp(obj2)
d 403.428793
b 1096.633158
a 0.006738
c 20.085537
dtype: int64
'b' in obj2
True
'e' in obj2
False
使用字典生成一个Series:
sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000}
obj3 = pd.Series(sdata)
obj3
Ohio 35000
Oregon 16000
Texas 71000
Utah 5000
dtype: int64
指定字典键传入构造函数:
states = ['California', 'Ohio', 'Oregon', 'Texas']
obj4 = pd.Series(sdata, index=states)
obj4
California NaN
Ohio 35000.0
Oregon 16000.0
Texas 71000.0
dtype: float64
注:California不在sdata的键中,故对应的值为NaN;Utah不在states中,故被排除在结果对象外。
pd.isnull(obj4)
// 也可以用 obj4.isnull
California True
Ohio False
Oregon False
Texas False
dtype: bool
pd.notnull(obj4)
// 也可以用 obj4.notnull()
California False
Ohio True
Oregon True
Texas True
dtype: bool
自动对齐索引:
obj3 + obj4
California NaN
Ohio 70000.0
Oregon 32000.0
Texas 142000.0
Utah NaN
dtype: float64
name属性:
obj4.name = 'population'
obj4.index.name = 'state'
obj4
state
California NaN
Ohio 35000.0
Oregon 16000.0
Texas 71000.0
Name: population, dtype: float64
通过按位赋值改变Series的索引:
obj
0 4
1 7
2 -5
3 3
dtype: int64
obj.index = ['Bob', 'Steve', 'Jeff', 'Ryan']
obj
Bob 4
Steve 7
Jeff -5
Ryan 3
dtype: int64
1.2 DataFrame
DataFrame
表示的是矩阵的数据表,包含已排序的列集合,每一列可以是不同的值类型(数值、字符串、布尔值等)。
data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'],
'year': [2000, 2001, 2002, 2001, 2002, 2003],
'pop': [1.5, 1.7, 3.6, 2.4, 2.9, 3.2]}
frame = pd.DataFrame(data)
frame
pop state year
0 1.5 Ohio 2000
1 1.7 Ohio 2001
2 3.6 Ohio 2002
3 2.4 Nevada 2001
4 2.9 Nevada 2002
5 3.2 Nevada 2003
head()
:选出头部的5行
frame.head()
pop state year
0 1.5 Ohio 2000
1 1.7 Ohio 2001
2 3.6 Ohio 2002
3 2.4 Nevada 2001
4 2.9 Nevada 2002
指定列的顺序:
pd.DataFrame(data, columns=['year', 'state', 'pop'])
year state pop
0 2000 Ohio 1.5
1 2001 Ohio 1.7
2 2002 Ohio 3.6
3 2001 Nevada 2.4
4 2002 Nevada 2.9
5 2003 Nevada 3.2
若传入的列不在字典中,则结果中出现缺失值:
frame2 = pd.DataFrame(data, columns=['year', 'state', 'pop', 'debt'],
index=['one', 'two', 'three', 'four',
'five', 'six'])
frame2
year state pop debt
one 2000 Ohio 1.5 NaN
two 2001 Ohio 1.7 NaN
three 2002 Ohio 3.6 NaN
four 2001 Nevada 2.4 NaN
five 2002 Nevada 2.9 NaN
six 2003 Nevada 3.2 NaN
frames.columns
Index(['year', 'state', 'pop', 'debt'], dtype='object')
检索DataFrame中的某一列:
frames2['state']
one Ohio
two Ohio
three Ohio
four Nevada
five Nevada
six Nevada
Name: state, dtype: object
根据属性索引:
frames.year
one 2000
two 2001
three 2002
four 2003
five 2002
six 2003
Name: year, dtype: int64
通过位置或特殊属性loc
进行行的选取:
frames.loc['three']
year 2002
state Ohio
pop 3.6
debt NaN
Name: three, dtype: object
修改列引用,赋值为标量值:
frame2['debt'] = 16.5
frame2
year state pop debt
one 2000 Ohio 1.5 16.5
two 2001 Ohio 1.7 16.5
three 2002 Ohio 3.6 16.5
four 2001 Nevada 2.4 16.5
five 2002 Nevada 2.9 16.5
six 2003 Nevada 3.2 16.5
修改列引用,赋值为值数组:
frame2['debt'] = np.arange(6.)
frame2
year state pop debt
one 2000 Ohio 1.5 0.0
two 2001 Ohio 1.7 1.0
three 2002 Ohio 3.6 2.0
four 2001 Nevada 2.4 3.0
five 2002 Nevada 2.9 4.0
six 2003 Nevada 3.2 5.0
将Series赋值给一列时,Series的索引将会按照DataFrame的索引重新排列,并在空缺处填充缺失值:
val = pd.Series([-1.2, -1.5, -1.7], index=['two', 'four', 'five'])
frame2['debt'] = val
frame2
year state pop debt
one 2000 Ohio 1.5 NaN
two 2001 Ohio 1.7 -1.2
three 2002 Ohio 3.6 NaN
four 2001 Nevada 2.4 -1.5
five 2002 Nevada 2.9 -1.7
six 2003 Nevada 3.2 NaN
若被赋值的列不存在,则会生成一个新的列:
frame2['eastern'] = frame2.state == 'Ohio'
frame2
year state pop debt eastern
one 2000 Ohio 1.5 NaN True
two 2001 Ohio 1.7 -1.2 True
three 2002 Ohio 3.6 NaN True
four 2001 Nevada 2.4 -1.5 False
five 2002 Nevada 2.9 -1.7 False
six 2003 Nevada 3.2 NaN False
注:frames2.eastern的语法无法创建新的列。
使用del
方法移除之前新建的列:
del frames2['eastern']
frames.columns
Index(['year', 'state', 'pop', 'debt'], dtype='object')
从Dataframe中选取的列是数据的视图,而不是拷贝,因此对Series的修改会映射到DataFrames中。故而需要显式地使用Series的 copy()方法进行复制.
包含字典的嵌套字典:
pop = {'Nevada': {2001: 2.4, 2002: 2.9},
'Ohio': {2000: 1.5, 2001: 1.7, 2002: 3.6}}
frame3 = pd.DataFrame(pop)
frame3
// 字典的键作为DataFrame的列,内部字典的键作为行索引
Nevada Ohio
2000 NaN 1.5
2001 2.4 1.7
2002 2.9 3.6
对DataFrame进行转置操作:
frame3.T
2000 2001 2002
Nevada NaN 2.4 2.9
Ohio 1.5 1.7 3.6
若已经显式指明索引,则内部字典的键将不会被排序:
pd.DataFrame(pop, index=[2001, 2002, 2003])
Nevada Ohio
2001 2.4 1.7
2002 2.9 3.6
2003 NaN NaN
包含Series的字典也可用于构造DataFrame:
pdata = {'Ohio': frame3['Ohio'][:-1],
'Nevada': frame3['Nevada'][:2]}
pd.DataFrame(pdata)
Nevada Ohio
2000 NaN 1.5
2001 2.4 1.7
当DataFrame的索引和列拥有name属性时,显示name属性:
frame3.index.name = 'year'; frame3.columns.name = 'state'
frame3
state Nevada Ohio
year
2000 NaN 1.5
2001 2.4 1.7
2002 2.9 3.6
以二维ndarray的形式返回DataFrame中的数据:
frames3.values
array([[nan, 1.5],
[2.4, 1.7],
[2.9, 3.6]])
若DataFrame的列是不同的dtypes,则values的dtype会自动选择适合所有列的类型:
frames2.values
array([[2000, 'Ohio', 1.5, nan],
[2001, 'Ohio', 1.7, -1.2],
[2002, 'Ohio', 3.6, nan],
[2001, 'Nevada', 2.4, -1.5],
[2002, 'Nevada', 2.9, -1.7],
[2003, 'Nevada', 3.2, nan]], dtype=object)
1.3 索引对象
Pandas中的索引对象是用于存储轴标签和其他元数据的(例如轴名称或标签)。
obj = pd.Series(range(3), index=['a', 'b', 'c'])
index = obj.index
index
Index(['a', 'b', 'c'], dtype='object')
index[1:]
Index(['b', 'c'], dtype='object')
索引对象是不可变的,故 index[1] = 'd' # TypeError
labels = pd.Index(np.arange(3))
labels
Int64Index([0, 1, 2], dtype='int64')
obj2 = pd.Series([1.5, -2.5, 0], index=labels)
obj2
0 1.5
1 -2.5
2 0.0
dtype: float64
obj2.index is labels
True
frame3
state Nevada Ohio
year
2000 NaN 1.5
2001 2.4 1.7
2002 2.9 3.6
frame3.columns
Index(['Nevada', 'Ohio'], dtype='object', name='state')
'Ohio' in frame3.columns
True
2003 in frame3.index
False
Pandas索引对象可以包含重复标签:
dup_labels = pd.Index(['foo', 'foo', 'bar', 'bar'])
dup_labels
Index(['foo', 'foo', 'bar', 'bar'], dtype='object')
2. 基本功能
2.1 重建索引
reindex()
:用于创建一个符合新索引的新对象。
obj = pd.Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c'])
obj
d 4.5
b 7.2
a -5.3
c 3.6
dtype: float64
若某索引值之前不存在,则会引入缺失值:
obj2 = obj.reindex(['a', 'b', 'c', 'd', 'e'])
obj2
a -5.3
b 7.2
c 3.6
d 4.5
e NaN
dtype: float64
ffill()
:在重建索引时插值,将值前向填充。
obj3 = pd.Series(['blue', 'purple', 'yellow'], index=[0, 2, 4])
obj3
0 blue
2 purple
4 yellow
dtype: object
obj3.reindex(range(6), method='ffill')
0 blue
1 blue
2 purple
3 purple
4 yellow
5 yellow
dtype: object
仅传入一个序列,行重建索引:
frame = pd.DataFrame(np.arange(9).reshape((3, 3)),
index=['a', 'c', 'd'],
columns=['Ohio', 'Texas', 'California'])
frame
Ohio Texas California
a 0 1 2
c 3 4 5
d 6 7 8
frame2 = frame.reindex(['a', 'b', 'c', 'd'])
frame2
Ohio Texas California
a 0.0 1.0 2.0
b NaN NaN NaN
c 3.0 4.0 5.0
d 6.0 7.0 8.0
使用column
关键字重建列索引:
states = ['Texas', 'Utah', 'California']
frame.reindex(columns=states)
Texas Utah California
a 1 NaN 2
c 4 NaN 5
d 7 NaN 8
使用loc
进行标签索引:
frame.loc[['a', 'b', 'c', 'd'], states]
Texas Utah California
a 1.0 NaN 2.0
b NaN NaN NaN
c 4.0 NaN 5.0
d 7.0 NaN 8.0
2.2 轴向上删除条目
drop()
:返回一个含有指示值或轴向上删除值的新对象。
obj = pd.Series(np.arange(5.), index=['a', 'b', 'c', 'd', 'e'])
obj.drop(['d', 'c'])
a 0.0
b 1.0
e 4.0
dtype:float64
在DataFrame中,索引值从轴向上删除:
data = pd.DataFrame(np.arange(16).reshape((4, 4)),
index=['Ohio', 'Colorado', 'Utah', 'New York'],
columns=['one', 'two', 'three', 'four'])
// 在调用drop时,使用标签序列会根据行标签删除值(轴0)
data.drop(['Colorado', 'Ohio'])
one two three four
Utah 8 9 10 11
New York 12 13 14 15
通过传递axis=1
从列中删除值:
data.drop('two', axis=1)
one three four
Ohio 0 2 3
Colorado 4 6 7
Utah 8 10 11
New York 12 14 15
通过传递axis='columns'
从列中删除值:
data.drop(['two', 'four'], axis='columns')
one three
Ohio 0 2
Colorado 4 6
Utah 8 10
New York 12 14
drop操作改变Series或者DataFrame的尺寸或形状,直接操作原对象而不返回新对象:
// inplace属性会清除被删除的数据
obj.drop('c', inplace=True)
obj
a 0.0
b 1.0
d 3.0
e 4.0
dtype: float64
2.3 索引、选择与过滤
Series的索引可以不仅仅为整数。
obj = pd.Series(np.arange(4.), index=['a', 'b', 'c', 'd'])
obj['b']
1.0
obj[1]
1.0
obj[2: 4]
c 2.0
d 3.0
dtype: float64
obj[['b', 'a', 'd']]
b 1.0
a 0.0
d 3.0
dtype: float64
obj[[1, 3]]
b 1.0
d 3.0
dtype: float64
obj[obj < 2]
a 0.0
b 1.0
dtype: float64
Series的切片包含尾部:
obj['b':'c']
b 1.0
c 2.0
dtype: float64
obj['b':'c'] = 5
obj
a 0.0
b 5.0
c 5.0
d 3.0
dtype: float64
使用单个值或序列,从DataFrame中索引出一个或多个列:
data = pd.DataFrame(np.arange(16).reshape((4, 4)),
index=['Ohio', 'Colorado', 'Utah', 'New York'],
columns=['one', 'two', 'three', 'four'])
data['two']
Ohio 1
Colorado 5
Utah 9
New York 13
Name: two, dtype: int64
data[['three', 'one']]
three one
Ohio 2 0
Colorado 6 4
Utah 10 8
New York 14 12
传递单个元素或一个列表到[]
符号中可以选择列:
data[data['three'] > 5]
one two three four
Colorado 4 5 6 7
Utah 8 9 10 11
New York 12 11 14 15
使用布尔值DataFrame进行索引:
data < 5
one two three four
Ohio True True True True
Colorado True False False False
Utah False False False False
New York False False False False
data[data < 5] = 0
data
one two three four
Ohio 0 0 0 0
Colorado 0 5 6 7
Utah 8 9 10 11
New York 12 13 14 15
2.3.1 使用loc和iloc选择数据
轴标签loc
和整数标签iloc
通过轴标签选出单行多列的数据:
data.loc['Colorado', ['two', 'three']]
two 5
three 6
Name: Colorado, dtype: int64
使用整数标签iloc进行类似的数据选择:
// 第三行的第四、一、二列
data.iloc[2, [3, 0, 1]]
four 11
one 8
two 9
Name: Utah, dtype: int64
// 第三行的所有列
data.iloc[2]
one 8
two 9
three 10
four 11
Name: Utah, dtype: int64
// 第二、三行的第四、一、二列
data.iloc[[1, 2], [3, 0, 1]]
one two three
Colorado 0 5 6
Utah 8 9 10
New York 12 13 14
索引功能用于切片:
// Utah行之前的所有行的‘two’列
data.loc[:'Utah', 'two']
Ohio 1
Colorado 5
Utah 9
Name: two, dtype: int64
// 所有行的前三列中数值大于5的
data.iloc[:, :3][data.three > 5]
one two three
Colorado 0 5 6
Utah 8 9 10
New York 12 13 14
2.4 整数索引
ser = pd.Series(np.arange(3.))
ser[:1]
0 0.0
dtype: float64
⭐4loc 与 iloc 的对比
loc
用于标签
ser.loc[:1]
0 0.0
1 1.1
dtype: float64
iloc
用于整数
ser.iloc[:1]
0 0.0
dtype: float64
2.5 算术和数据对齐
s1 = pd.Series([7.3, -2.5, 3.4, 1.5], index=['a', 'c', 'd', 'e'])
s2 = pd.Series([-2.1, 3.6, -1.5, 4, 3.1],
index=['a', 'c', 'e', 'f', 'g'])
s1 + s2
a 5.2
c 1.1
d NaN
e 0.0
f NaN
g NaN
dtype: float64
DataFrame的行和列执行对其
df1 = pd.DataFrame(np.arange(9.).reshape((3, 3)), columns=list('bcd'),
index=['Ohio', 'Texas', 'Colorado'])
df2 = pd.DataFrame(np.arange(12.).reshape((4, 3)), columns=list('bde'),
index=['Utah', 'Ohio', 'Texas', 'Oregon'])
df1 + df2
b c d e
Colorado NaN NaN NaN NaN
Ohio 3.0 NaN 6.0 NaN
Oregon NaN NaN NaN NaN
Texas 9.0 NaN 12.0 NaN
Utah NaN NaN NaN NaN
将两个行、列完全不同的DataFrame对象相加:
df1 = pd.DataFrame({'A': [1, 2]})
df2 = pd.DataFrame({'B': [3, 4]})
df1 - df2
A B
0 NaN NaN
1 NaN NaN
2.5.1 使用填充值的算术方法
df1 = pd.DataFrame(np.arange(12.).reshape((3, 4)),
columns=list('abcd'))
df2 = pd.DataFrame(np.arange(20.).reshape((4, 5)),
columns=list('abcde'))
// df2的第二行(行索引为1)的列索引为‘b’的那个元素置为NaN
df2.loc[1, 'b'] = np.nan
在df1上使用add
方法,将df2和一个fill_value
作为参数传入:
df1.add(df2, fill_value=0)
a b c d e
0 0.0 2.0 4.0 6.0 4.0
1 9.0 5.0 13.0 15.0 9.0
2 18.0 20.0 22.0 24.0 14.0
3 15.0 16.0 17.0 18.0 19.0
求倒数
1 / df1
// 等价于df1.rdiv(1)
a b c d
0 inf 1.000000 0.500000 0.333333
1 0.250000 0.200000 0.166667 0.142857
2 0.125000 0.111111 0.100000 0.090909
重建索引:
df1.reindex(columns=df2.columns, fill_value=0)
a b c d e
0 0.0 1.0 2.0 3.0 0
1 4.0 5.0 6.0 7.0 0
2 8.0 9.0 10.0 11.0 0
2.5.2 DataFrame和Series间的操作
arr = np.arange(12.).reshape((3, 4))
// 广播机制
arr - arr[0]
array([[0., 0., 0., 0.],
[4., 4., 4., 4.],
[8., 8., 8., 8.]])
frame = pd.DataFrame(np.arange(12.).reshape((4, 3)),
columns=list('bde'),
index=['Utah', 'Ohio', 'Texas', 'Oregon'])
series = frame.iloc[0]
series
b 0.0
d 1.0
e 2.0
Name: Utah, dtype: float64
默认情况下,Series的索引和DataFrame的列进行匹配,并广播到各行:
frame - series
b d e
Utah 0.0 0.0 0.0
Ohio 3.0 3.0 3.0
Texas 6.0 6.0 6.0
Oregon 9.0 9.0 9.0
若一个索引值不在DataFrame的列中,也不在Series的索引中,则对象会重建索引并形成联合:
series2 = pd.Series(range(3), index=['b', 'e', 'f'])
frame + series2
b d e f
Utah 0.0 NaN 3.0 NaN
Ohio 3.0 NaN 6.0 NaN
Texas 6.0 NaN 9.0 NaN
Oregon 9.0 NaN 12.0 NaN
在列上进行广播:
series3 = frame['d']
frame.sub(series3, axis='index')
// 或者axis=0
b d e
Utah -1.0 0.0 1.0
Ohio -1.0 0.0 1.0
Texas -1.0 0.0 1.0
Oregon -1.0 0.0 1.0
2.6 函数应用和映射
NumPy的逐元素数组方法对Pandas对象也有效:
frame = pd.DataFrame(np.random.randn(4, 3), columns=list('bde'),
index=['Utah', 'Ohio', 'Texas', 'Oregon'])
// 将构建的4 * 3的二维数组的值转为绝对值
np.abs(frame)
计算Series的最大值和最小值的差
// frame的每一列都会调用一次,结果是以frame的列为索引的Series
f = lambda x: x.max() - x.min()
frame.apply(f)
b 1.802165
d 1.684034
e 2.689627
dtype: float64
传递axis='columns'
给apply()
函数,函数将被每行调用一次:
frame.apply(f, axis='columns')
Utah 0.998382
Ohio 2.521511
Texas 0.676115
Oregon 2.542656
dtype: float64
传递给apply()
的函数可以返回带有多个值的Series:
def f(x):
return pd.Series([x.min(), x.max()], index=['min', 'max'])
frame.apply(f)
b d e
min b列最小值 d列最小值 e列最小值
max b列最大值 d列最大值 e列最大值
根据frame中的每个浮点数计算一个格式化字符串:
format = lambda x: '%.2f' % x
frame.applymap(format)
b d e
Utah -0.20 0.48 -0.52
Ohio -0.56 1.97 1.39
Texas 0.09 0.28 0.77
Oregon 1.25 1.01 -1.30
将逐元素应用到Series上:
Utah -0.52
Ohio 1.39
Texas 0.77
Oregon -1.30
Name: e, dtype: object
2.7 排序和排名
sort_index()
:返回一个新的、排序好的对象。
obj = pd.Series(range(4), index=['d', 'a', 'b', 'c'])
obj.sort_index()
a 1
b 2
c 3
d 0
dtype: int64
在各个轴上按索引进行排序:
frame = pd.DataFrame(np.arange(8).reshape((2, 4)),
index=['three', 'one'],
columns=['d', 'a', 'b', 'c'])
frame.sort_index()
b a b c
one 4 5 6 7
three 0 1 2 3
frame.sort_index(axis=1)
a b c d
three 1 2 3 0
one 5 6 7 4
默认按升序排序,也可设置ascending
按降序排列:
frame.sort_index(axis=1, ascending=False)
d c b a
three 0 3 2 1
one 4 7 6 5
根据Series的值进行排序,使用sort_values():
obj = pd.Series([4, 7, -3, 2])
obj.sort_values()
2 -3
3 2
0 4
1 7
dtype: int64
默认情况下,所有的缺失值都会被排序至Series的尾部:
obj = pd.Series([4, np.nan, 7, np.nan, -3, 2])
obj.sort_values()
4 -3.0
5 2.0
0 4.0
2 7.0
1 NaN
3 NaN
dtype: float64
使用一列或多列作为排序键对DataFrame排序:
frame = pd.DataFrame({'b': [4, 7, -3, 2], 'a': [0, 1, 0, 1]})
frame.sort_values(by='b')
a b
2 0 -3
3 1 2
0 0 4
1 1 7
对多列排序:
frame.sort_values(by=['a', 'b'])
a b
2 0 -3
0 0 4
3 1 2
1 1 7
排名:对数组从1到有效数据点总数分配名次的操作。
obj = pd.Series([7, -5, 7, 4, 2, 0, 4])
obj.rank()
0 6.5
1 1.0
2 6.5
3 4.5
4 3.0
5 2,0
6 4.5
dtype: float64
obj.rank(method='first')
0 6.0
1 7.0
3 4.0
4 3.0
5 2.0
6 5.0
dtype: float64
将值分配给组中的最大排名:
obj.rank(ascending=False, method='max')
0 2.0
1 7.0
2 2.0
3 4.0
4 5.0
5 6.0
6 4.0
dtype: float64
对行或列计算排名:
frame = pd.DataFrame({'b': [4.3, 7, -3, 2], 'a': [0, 1, 0, 1],
'c': [-2, 5, 8, -2.5]})
frame.rank(axis='columns')
a b c
0 2.0 3.0 1.0
1 1.0 3.0 2.0
2 2.0 1.0 3.0
3 2.0 3.0 1.0
2.8 含有重复标签的轴索引
is_unique属性
:判断标签是否唯一
obj = pd.Series(range(5), index=['a', 'a', 'b', 'b', 'c'])
obj.index.is_unique
False
根据一个标签索引多个条目会返回一个序列,而单个条目会返回标量值:
obj['a']
a 0
a 1
dtype: int64
obj['b']
4
3. 描述性统计的概述和计算
df = pd.DataFrame([[1.4, np.nan], [7.1, -4.5],
[np.nan, np.nan], [0.75, -1.3]],
index=['a', 'b', 'c', 'd'],
columns=['one', 'two'])
// 默认返回一个包含列上求和的Series
df.sum()
one 9.25
two -5.8
dtype: float64
传入axis='columns'
或者axis=1
,则将返回各行上的各个列的值的和
df.sum(axis='columns')
a 1.40
b 2.60
c NaN
d -0.55
dtype: float64
通过禁用skipna
来实现不排除NA值:
df.mean(axis='columns', skipna=False)
a NaN
b 1.300
c NaN
d -0.275
dtype: float64
返回每列中最大值的索引值:
df.idxmax()
one b
two d
dtype: object
求累计值
df.cumsum()
one two
a 1.40 NaN
b 8.50 -4.5
c NaN NaN
d 9.25 -5.8
一次性产生多个汇总统计:
df.describe()
one two
count 3.000000 2.000000
mean 3.083333 -2.900000
std 3.493685 2.262742
min 0.750000 -4.500000
25% 1.075000 -3.700000
50% 1.400000 -2.900000
75% 4.250000 -2.100000
max 7.100000 -1.300000
对于非数值型数据:
obj = pd.Series(['a', 'a', 'b', 'c'] * 4)
obj.describe()
count 16
unique 3
top a
freq 8
dtype: object
3.1 相关性和协方差
获取股票行情:
import pandas_datareader.data as web
all_data = {ticker: web.get_data_yahoo(ticker) for ticker in ['AAPL', 'IBM', 'MSFT', 'GOOG']}
price = pd.DataFrame({ticker: data['Adj Close']
for ticker, data in all_data.items()})
volume = pd.DataFrame({ticker: data['Volume']
for ticker, data in all_data.items()})
计算股价的百分比:
returns = price.pct_change()
returns.tail()
AAPL GOOG IBM MSFT
Date
2016-10-17 -0.000680 ...
2016-10-18
2016-10-19 ...
2016-10-20 ...
2016-10-21
计算相关性:
returns['MSFT'].corr(returns['IBM'])
// 等价于 returns.MSFT.corr(returns.IBM)
计算协方差:
returns['MSFT'].cov(returns['IBM'])
返回相关性矩阵:
returns.corr()
// 对称矩阵
AAPL GOOG IBM MSFT
AAPL 1.000000 0.407919 0.386817 0.389695
GOOG ...
IBM ...
MSFT ...
返回协方差矩阵:
returns.cov()
AAPL GOOG IBM MSFT
AAPL ...
GOOG ...
IBM ...
MSFT ...
计算DataFrame中的行或列与另一个序列或DataFrame的相关性:
returns.corrwith(returns.IBM)
// 返回一个含有为每列计算相关性值的Series
AAPL 0.386817
GOOG 0.405099
IBM 1.000000
MSFT 0.499764
dtype: float64
计算交易量百分比变化的相关性:
returns.corrwith(volume)
AAPL -0.075565
GOOG -0.007067
IBM -0.204849
MSFT 0-0.092950
dtype: float64
3.2 唯一值、计数和成员属性
obj = pd.Series(['c', 'a', 'd', 'a', 'a', 'b', 'b', 'c', 'c'])
uniques = obj.unique()
uniques
array(['c', 'a', 'd', 'b', dtype=object])
计算Series包含的值的个数:
obj.value_counts()
c 3
a 3
b 2
d 1
dtype: int64
value_counts是pandas的顶层方法:
pd.value_counts(obj.values, sort=False)
a 3
b 2
c 3
d 1
dtype: int64
isin
执行向量化的成员属性检查:
mask = obj.isin(['b', 'c'])
mask
0 True
1 False
2 False
3 False
4 False
5 True
6 True
7 True
8 True
dtype: bool
obj[mask]
0 c
5 b
6 b
7 c
8 c
dtype: object
将可能非唯一数组转换为另一个唯一值数组:
to_match = pd.Series(['c', 'a', 'b', 'b', 'c', 'a'])
unique_vals = pd.Series(['c', 'b', 'a'])
pd.Index(unique_vals).get_indexer(to_match)
array([0, 2, 1, 1, 0, 2])
计算多个相关列的直方图:
data = pd.DataFrame({'Qu1': [1, 3, 4, 3, 4],
'Qu2': [2, 3, 1, 2, 3],
'Qu3': [1, 5, 2, 4, 4]})
data
将pandas.value_counts传入DataFrame的apply()函数:
result = data.apply(pd.value_counts).fillna(0)
result
Qu1 Qu2 Qu3
1 1.0 1.0 1.0
2 0.0 2.0 1.0
3 2.0 2.0 0.0
4 2.0 0.0 2.0
5 0.0 0.0 1.0