pandas中的重要数据结构
Series:
Series类似与一维数组,它可以由两个属性来表示:index
和values
In [127]: obj = pd.Series([4, 7, -5, 3])
In [128]: obj.index
Out[128]:
RangeIndex(start=0, stop=4, step=1)
In [129]: obj.values
Out[129]:
array([ 4, 7, -5, 3], dtype=int64)
同时,Series又和Python中的字典密不可分。
In [57]: sdata = {'what': 23, 'amazing': 6, 'happened': 23}
In [58]: sdata
Out[58]:
{'amazing': 6, 'happened': 23, 'what': 23}
In [60]: obj3 = pd.Series(sdata)
In [61]: obj3
Out[61]:
amazing 6
happened 23
what 23
dtype: int64
不存在的值可以用pd.isnull()
和pd.notnull()
来判断,此外,Series及其中的索引(index)都可以有名字,也就是Series.name
和Series.index.name
。
DataFrame:
DataFrame用于处理二维数据。如果把Series看成一个列向量,那么DataFrame就是一个列向量组,它与数组和字典同样保持着密切的联系。DataFrame有三个重要的属性:index
行索引、columns
列索引、values
数据值。我通常把DataFrame的columns(列名)理解成Series的name属性。
下表是可以输入给DataFrame构造器的数据
类型 | 说明 |
---|---|
二维ndarray | 数据矩阵,还可以传入行标和列标 |
有数组、列表或元组组成的字典 | 每个序列会变成DataFrame的一列。所有序列的长度必须相同 |
Numpy的结构化/记录数组 | 类似于“由数组组成的字典” |
由Series组成的字典 | 每个Series会成为一列。如果没有显示指定索引,则各Series的索引会被合并成结果的行索引 |
由字典组成的字典 | 各内层字典会成为一列。键会被合并成结果的行索引,跟“由Series组成的字典”情况一样 |
字典或Series的列表 | 各项将会成为DataFrame的一行。字典键或Series索引的并集将会成为DataFrame的列标 |
由列表或元组组成的列表 | |
另一个DataFrame | |
Numpy的MarkedArray | 类似于“二维ndarray”的情况,只是掩码值再结果DataFrame会变成NA/缺失值 |
对于数据类型,可以在导入给DataFrame构造器时通过pd.DataFrame()
中的参数dtype
来确定,或者在导入后通过testdf['列名'].astype()
来改变。默认情况下,如果DataFrame各列的数据类型不同,则值数组的数据类型就会选用能兼容所有列的数据类型,通常是python.object
Pandas中的主要索引对象
index对象是不可修改的(immutable),因此用户不能对其进行修改,但是可以替换。不可修改行非常重要,因为这样才能使index对象再多个数据结构之间安全共享。
- 重新索引的方法有二
-
testseries.reindex()
或testdf.reindex()
,但是这个函数只支持输入不重复的情况 -
直接改变series或者dataframe的
index
属性
reindex函数的参数:
参数 | 说明 |
---|---|
index | 用做索引的新序列。既可以是Index实例,也可以是其他序列的Python数据结构。Index会被完全使用,就像没有任何复制一样 |
method | 插值(填充)方式 |
fill_value | 在重新索引的过程中,需要引入缺失值时使用的替代值 |
limit | 前向或后向填充时的最大最大填充量 |
level | 在MultiIndex的指定级别上匹配简单索引,否则选取其子集 |
copy | 默认为True,无论如何都复制;如果为False,则新旧相等就不复制 |
reindex的method选项:
参数 | 说明 |
---|---|
ffill或pad | 前向填充(或搬运)值 |
bfill或backfill | 后向填充(或搬运)值 |
pandas中主要的index对象:
类 | 说明 |
---|---|
Index | 最泛化的Index对象,将轴标签表示为一个有Python对象组成的Numpy数组 |
Int64Index | 针对整数的特殊Index |
MultiIndex | “层次化”索引对象,表示单个轴上的多层索引。可以看做有元组组成的数组 |
DatetimeIndex | 存储纳秒级时间戳(用Numpy的datetime64类型表示) |
PeriodIndex | 针对Period数据(时间间隔)的特殊Index |
index的方法和属性
方法 | 说明 |
---|---|
append | 连接另一个index对象,产生一个新的index |
diff | 计算差集,并得到一个新的index |
intersection | 计算交集 |
union | 计算并集 |
isin | 计算一个指示各值是否都包含在参数集合中的bool型数组 |
delete | 删除suoyini处的元素,并得到新的index |
drop | 删除传入的值,并得到新的index |
insert | 将元素插入到索引i处,并得到新的index |
is_monotonic | 当各元素均大于等于前一个元素时,返回True |
is_unique | 当index中没有重复元素时,返回True |
unique | 计算index中唯一值的数组 |
索引、选取和过滤
见10 minutes to pandas
PS:可以通过选取来构建新的DataFrame
In [94]: data
Out[94]:
A B C E
a 0 1 2 3
b 4 5 6 4
c 8 9 10 5
In [95]: data.loc[['a', 'd'], ['A', 'B', 'D']]
Out[95]:
A B D
a 0.0 1.0 NaN
算数运算
加减乘除运算
In[98]: df1
Out[98]:
b c d
Ohio 0 1 2
Texas 3 4 5
Colorado 6 7 8
In[99]: df2
Out[99]:
b d e
Utah 0 1 2
Ohio 3 4 5
Texas 6 7 8
Oregon 9 10 11
In[100]: df1 + df2
Out[100]:
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
灵活的算术方法
方法 | 说明 |
---|---|
add | + |
sub | - |
div | * |
mul | / |
DataFrame和Series之间的运算
默认情况下,Data Frame和Series之间的算术运算会将Series的索引匹配到DataFrame的列,然后沿着行一直向下广播。如果某个索引值再DataFrame的列或Series的索引中找不到,则参与运算的两个对象就会被重新索引一形成并集。
PS: 如果希望匹配行且再列上广播,则必须使用算术运算方法。
函数应用和映射
- 在行或列上的函数应用
-
testdf.apply()
- 在dataframe元素级上的函数应用
-
f = lambda x: '%.2f' %x
-
testdf.applymap()
- 在Series上的函数应用
-
testseries.map(f)
排序
Series和DataFrame都有sort_index(axis=1, ascending=False)
和sort_values()
, Series还有order()
。
其中axis=1
表示沿列广播,ascending=False
表示降序排列。
汇总和计算表述统计
描述和汇总统计:
方法 | 说明 |
---|---|
count | 非NA的数量 |
describe | 针对Series或各DataFrame列计算汇总统计 |
min, max | |
argmin, argmax | |
quantile | |
sum | |
mean | |
median | |
mad | 根据平均值计算平均绝对离差 |
var | 样本值的方差 |
std | |
skew | 样本值的偏离度(三阶矩) |
kurt | 样本值的峰度(四阶矩) |
cumsum | 样本值的累计和 |
cummin, cummax | 样本和的累计最大值和累计最小值 |
cumprod | 样本值的累计积 |
diff | 计算一阶差分(对时间序列很有用) |
pct_change | 计算百分数的变化 |
约简方法的选项:
选项 | 说明 |
---|---|
axis | 约简的轴。DataFrame的行用0,列用1 |
skipna | 排除缺失值,默认值为True |
leve | 如果轴是层次化索引的(MultiIndex),则根据level分组约简 |
相关系数和协方差
相关系数testseries.corr(testseries)
和协方差testseries.cov(testseries)
返回的都是一个矩阵,矩阵的行和列是输入的索引,矩阵是对称的。
唯一值、值计数以及成员资格
唯一值、值计数以及成员资格:
方法 | 说明 |
---|---|
isin | |
unique | 输入是Series |
value_counts | 返回一个Series,其索引为唯一值,其值为频率,按计数值降序排列 |
处理缺失数据
NA1处理方法:
方法 | 说明 |
---|---|
dropna | 根据各标签的值中是否存在缺失数据对轴标签进行过滤,可通过与之调节对缺失值的容忍度 |
fillna | |
isnull | |
notnull |
PS:testdf[testdf.notnull()] == testdf.dropna()
2
fillna函数的参数:
参数 | 说明 |
---|---|
value | 用于填充缺失值的标量值或字典对象 |
method | 插值方式。如果函数调用时为指定其他参数的话,默认为”ffill” |
axis | |
inplace | 默认”False”修改调用者对象而不产生副本 |
limit | 可以连续填充的最大数量 |
层次化索引
层次化索引是pandas的一项重要功能,它使你能在一个周上拥有多个索引级别。每一层都可以有名字。
对于一个双层的Series,可以testseries.unstack()
; 相反,对于一个DataFrame,可以testdf.stack()
。
In [114]: frame
Out[114]:
a b c d
0 0 7 one 0
1 1 6 one 1
2 2 5 one 2
3 3 4 two 0
4 4 3 two 1
5 5 2 two 2
6 6 1 two 3
In [115]: frame2 = frame.set_index(['c', 'd'], drop=False)
In [116]: frame2
Out[116]:
a b c d
c d
one 0 0 7 one 0
1 1 6 one 1
2 2 5 one 2
two 0 3 4 two 0
1 4 3 two 1
2 5 2 two 2
3 6 1 two 3
In [119]: frame2 = frame.set_index(['c', 'd'], drop=True)
In [120]: frame2
Out[120]:
a b
c d
one 0 0 7
1 1 6
2 2 5
two 0 3 4
1 4 3
2 5 2
3 6 1
In[121]: frame2.reset_index()
Out[121]:
c d a b
0 one 0 0 7
1 one 1 1 6
2 one 2 2 5
3 two 0 3 4
4 two 1 4 3
5 two 2 5 2
6 two 3 6 1