pandas入门(4)——基本功能
重新索引
方法reindex:其作用是创建一个新对象,它的数据符合新的索引,若某个索引值当前不存在,就引入缺失值
obj = pd.Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c'])
obj
obj2 = obj.reindex(['a', 'b', 'c', 'd', 'e'])
obj2
方法method:使用ffill可以实现前项值填充,适用于时间序列等有序数据
obj3 = pd.Series(['blue', 'purple', 'yellow'], index=[0, 2, 4])
obj3
obj3.reindex(range(6), method='ffill')
reindex借助DataFrame可以修改索引行和列
只传递一个序列,会重新索引结果的行
frame = pd.DataFrame(np.arange(9).reshape((3, 3)),
index=['a', 'c', 'd'],
columns=['Ohio', 'Texas', 'California'])
frame
frame2 = frame.reindex(['a', 'b', 'c', 'd'])
frame2
重新索引列使用columns关键字
states = ['Texas', 'Utah', 'California']
frame.reindex(columns=states)
丢弃指定轴上的项
drop方法
obj = pd.Series(np.arange(5.), index=['a', 'b', 'c', 'd', 'e'])
obj
new_obj = obj.drop('c')
new_obj
obj.drop(['d', 'c'])
DataFrame中删除:
data = pd.DataFrame(np.arange(16).reshape((4, 4)),
index=['Ohio', 'Colorado', 'Utah', 'New York'],
columns=['one', 'two', 'three', 'four'])
data
#删除行
data.drop(['Colorado', 'Ohio'])
#删除列
data.drop('two', axis=1)
data.drop(['two', 'four'], axis='columns')
inplace方法
直接销毁所有被删除的数据,如
obj.drop('c', inplace=True)
索引、选取和过滤
Series数据结构
Series索引(obj[…])的工作方式类似于NumPy数组的索引,只不过Series的索引值不只是整数,如
obj = pd.Series(np.arange(4.), index=['a', 'b', 'c', 'd'])
obj
#查看'b'对应的值
obj['b']
#查看第一个值
obj[1]
#查看第三个与第四个值
obj[2:4]
#查看'b','a','d'对应的值
obj[['b', 'a', 'd']]
#选取值为1和3对应的数组
obj[[1, 3]]
#选取值小于2的数组
obj[obj < 2]
备注:利用标签的切片运算与普通的Python切片运算不同,其末端是包含的,如
obj['b':'c']
用切片可以对Series的相应部分进行设置,如
obj['b':'c'] = 5
DataFrame数据结构
data = pd.DataFrame(np.arange(16).reshape((4, 4)),
index=['Ohio', 'Colorado', 'Utah', 'New York'],
columns=['one', 'two', 'three', 'four'])
data
#选取第二列的数组
data['two']
#选取第一列、第三列的数组
data[['three', 'one']]
#选取前2行
data[:2]
#选取'threee'列值大于5的数组
data[data['three'] > 5]
#判断数值是否小于5
data < 5
data[data < 5] = 0
用loc和iloc进行选取
**iloc:基于位置,用行号、列号进行索引,**i 可以看着 int,因此 iloc 只能用整数来索引,例如data.iloc[0:2,:]
**loc :基于标签,用行名、列名进行索引,**数据的index经常为整数,因此 loc 的使用范围要远高于iloc,loc可以使用整数切片、名称(index,columns)索引、也可以切片和名称混合使用。例如:data.loc[0:5:,‘row1’:‘row2’]
data.loc['Colorado', ['two', 'three']]
data.loc[:'Utah', 'two']
data.iloc[:, :3][data.three > 5]
data.iloc[2, [3, 0, 1]]
data.iloc[2]
data.iloc[[1, 2], [3, 0, 1]]
整数索引
为了更准确,请使用loc(标签)或iloc(整数)
ser = pd.Series(np.arange(3.))
ser.loc[:1]
ser.iloc[:1]
算数运算与数据对齐
pandas可以对不同索引的对象进行算术运算。在将对象相加时,如果存在不同的索引对,则结果的索引就是该索引对的并集
在Series中
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
备注:自动的数据对齐操作在不重叠的索引处引入了NA值。缺失值会在算术运算过程中传播
DataFrame中
df1 = pd.DataFrame(np.arange(9.).reshape((3, 3)), columns=list('bcd'),
index=['Ohio', 'Texas', 'Colorado'])
df2 = pd.DataFrame(np.arange(12.).reshape((4, 3)), columns=list('bde'),
index=['Utah', 'Ohio', 'Texas', 'Oregon'])
备注:自动的数据对齐操作在不重叠的索引处引入了NA值
在算术方法填充值
在对不同索引的对象进行算术运算时,我们可能希望当一个对象中某个轴标签在另一个对象中找不到时填充一个特殊值(比如0):
df1 = pd.DataFrame(np.arange(12.).reshape((3, 4)),
columns=list('abcd'))
df2 = pd.DataFrame(np.arange(20.).reshape((4, 5)),
columns=list('abcde'))
df2.loc[1, 'b'] = np.nan
#相加时,没有重叠的位置会产生NA值
df1 + df2
#使用df1的add方法,传入df2以及一个fill_value参数(可尝试0与2的不同结果):
df1.add(df2, fill_value=0)
df1.add(df2, fill_value=2)
DataFrame和Series之间的运算
arr = np.arange(12.).reshape((3, 4))
arr
arr[0]
array([ 0., 1., 2., 3.])
arr - arr[0]
跟不同维度的NumPy数组一样,DataFrame和Series之间算术运算也是有明确规定的。当从arr减去arr[0],每一行都会执行这个操作。这就叫做广播(broadcasting):默认情况下,DataFrame和Series之间的算术运算会将Series的索引匹配到DataFrame的列,然后沿着行向下广播,如
frame = pd.DataFrame(np.arange(12.).reshape((4, 3)),
columns=list('bde'),
index=['Utah', 'Ohio', 'Texas', 'Oregon'])
series = frame.iloc[0]
frame
series
In [1]: frame - series
Out[1]:
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的索引中找不到,则参与运算的两个对象就会被重新索引以形成并集,如
In [2]: series2 = pd.Series(range(3), index=['b', 'e', 'f'])
In [3]: frame + series2
Out[3]:
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
匹配行,沿着列广播
必须使用算术运算方法
In [4]: series3 = frame['d']
In [5]: frame
Out[5]:
b d e
Utah 0.0 1.0 2.0
Ohio 3.0 4.0 5.0
Texas 6.0 7.0 8.0
Oregon 9.0 10.0 11.0
In [6]: series3
Out[6]:
Utah 1.0
Ohio 4.0
Texas 7.0
Oregon 10.0
Name: d, dtype: float64
In [7]: frame.sub(series3, axis='index')#传入的轴号是希望匹配的轴
Out[7]:
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
排序和排名
sort_index方法
根据条件对数据集排序(sorting)也是一种重要的内置运算。要对行或列索引进行排序(按字典顺序),可使用sort_index方法,它将返回一个已排序的新对象,如
In [8]: obj = pd.Series(range(4), index=['d', 'a', 'b', 'c'])
In [9]: obj.sort_index()
Out[9]:
a 1
b 2
c 3
d 0
对于DataFrame,则可以根据任意一个轴上的索引进行排序:
In [10]: frame = pd.DataFrame(np.arange(8).reshape((2, 4)),
index=['three', 'one'],
columns=['d', 'a', 'b', 'c'])
In [11]: frame.sort_index()
Out[11]:
d a b c
one 4 5 6 7
three 0 1 2 3
In [12]: frame.sort_index(axis=1)
Out[12]:
a b c d
three 1 2 3 0
one 5 6 7 4
备注:数据默认是按升序排序的,但也可以降序排序,如
In [13]: frame.sort_index(axis=1, ascending=False)
Out[13]:
d c b a
three 0 3 2 1
one 4 7 6 5
sort_values方法
若要按值对Series进行排序,可使用其sort_values方法,如
In [14]: obj = pd.Series([4, 7, -3, 2])
In [15]: obj.sort_values()
Out[15]:
2 -3
3 2
0 4
1 7
备注:在排序时,任何缺失值默认都会被放到Series的末尾,如
In [16]: obj = pd.Series([4, np.nan, 7, np.nan, -3, 2])
In [17]: obj.sort_values()
Out[17]:
4 -3.0
5 2.0
0 4.0
2 7.0
1 NaN
3 NaN
当排序一个DataFrame时,你可能希望根据一个或多个列中的值进行排序。将一个或多个列的名字传递给sort_values的by选项即可达到该目的:
In [18]: frame = pd.DataFrame({'b': [4, 7, -3, 2], 'a': [0, 1, 0, 1]})
In [19]: frame
Out[19]:
a b
0 0 4
1 1 7
2 0 -3
3 1 2
In [20]: frame.sort_values(by='b')
Out[20]:
a b
2 0 -3
3 1 2
0 0 4
1 1 7
要根据多个列进行排序,传入名称的列表即可:
In [21]: frame.sort_values(by=['a', 'b'])#先排a列,再排b列
Out[21]:
a b
2 0 -3
0 0 4
3 1 2
1 1 7
rank方法
rank是通过“为各组分配一个平均排名”的方式破坏平级关系的,如
In [22]: obj = pd.Series([7, -5, 7, 4, 2, 0, 4])
In [23]: obj.rank()#如果有两个值一样,分别在4,5,则他们的排名为4.5
Out[23]:
0 6.5
1 1.0
2 6.5
3 4.5
4 3.0
5 2.0
6 4.5
也可以根据值在原数据中出现的顺序给出排名,如
In [24]: obj.rank(method='first')#意思就是两个一样的值的话先出现的值排名高
Out[24]:
0 6.0
1 1.0
2 7.0
3 4.0
4 3.0
5 2.0
6 5.0
也可以按降序进行排名,如
In [25]: obj.rank(ascending=False, method='max')#max指两个一样的话都取排名高的那个排名
Out[25]:
0 2.0
1 7.0
2 2.0
3 4.0
4 5.0
5 6.0
6 4.0
DataFrame可以在行或列上计算排名:
In [26]: frame = pd.DataFrame({'b': [4.3, 7, -3, 2], 'a': [0, 1, 0, 1],
'c': [-2, 5, 8, -2.5]})
In [27]: frame
Out[27]:
a b c
0 0 4.3 -2.0
1 1 7.0 5.0
2 0 -3.0 8.0
3 1 2.0 -2.5
In [28]: frame.rank(axis='columns')
Out[28]:
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
带有重复标签的轴索引
pandas函数中允许带有重复索引值的Series,如
obj = pd.Series(range(5), index=['a', 'a', 'b', 'b', 'c'])
In [29]: obj
Out[29]:
a 0
a 1
b 2
b 3
c 4
索引的is_unique属性可以告诉你它的值是否是唯一的,如
In [30]: obj.index.is_unique
Out[30]: False
对于带有重复值的索引,数据选取的行为将会有些不同。如果某个索引对应多个值,则返回一个Series;而对应单个值的,则返回一个标量值,如
In [31]: obj['a']
Out[31]:
a 0
a 1
In [32]: obj['c']
Out[32]: 4
这样会使代码变复杂,因为索引的输出类型会根据标签是否有重复发生变化