Pandas一篇入门

数据结构

在Pandas中有两类非常重要的数据结构,即序列Series和数据框DataFrame。Series类似于NumPy中的一维ndarray数组,除了具备其一维数组可用的函数之外还具备索引的自动对齐功能。DataFrame类似于NumPy中的二维ndarray数组,同样在这个基础上新增了一些功能。

Series的创建

序列可以通过一维数组创建

In [1]: import pandas as pd
In [2]: import numpy as np
In [3]: arr = [n for n in range(10)]
In [4]: s1 = pd.Series(arr)
In [5]: print(s1)
0    0
1    1
2    2
3    3
4    4
5    5
6    6
7    7
8    8
9    9
dtype: int64

可以通过字典的方式创建

In [6]: dic = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5}
In [7]: dic = pd.Series(dic)
In [8]: print(dic)
a    1
b    2
c    3
d    4
e    5
dtype: int64

还可以利用DataFrame中的元素来创建序列

DataFrame的创建

DataFrame的创建有以下几种方式:
通过二维数组创建

In [9]: arr1 = np.arange(12).reshape(3,4)
In [10]: print(arr1)
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
In [11]: df1 = pd.DataFrame(arr1)
In [12]: print(df1)
   0  1   2   3
0  0  1   2   3
1  4  5   6   7
2  8  9  10  11
In [13]: print(type(df1))
<class 'pandas.core.frame.DataFrame'>

通过字典的方式创建

In [20]: dic1 = {'a':[1,2,3,4], 'b':[5,6,7,8], 'c':[9,10,11,12], 'd':[13,14,15,16]}
In [21]: df1 = pd.DataFrame(dic1)
In [22]: print(type(df1))
<class 'pandas.core.frame.DataFrame'>
In [23]: print(df1)
   a  b   c   d
0  1  5   9  13
1  2  6  10  14
2  3  7  11  15
3  4  8  12  16

还可以通过重构DataFrame对象或者选取子集来创建新的DataFrame

In [25]: df2 = df1[['a', 'b']]
In [26]: print(type(df2))
<class 'pandas.core.frame.DataFrame'>
In [27]: print(df2)
   a  b
0  1  5
1  2  6
2  3  7
3  4  8

数据索引

不难发现,Series和DataFrame对象的左边(或上面)总是有一组元素以外的数据。其实这些就是索引,它的作用不光是通过标签获取对应位置的元素,还可以使Series或DataFrame的计算和操作实现自动对齐。
定义完Series或DataFrame后可以通过index属性查看索引的起止和步长信息

In [36]: s2 = pd.Series(np.arange(100, 110))
In [37]: print(s2)
0    100
1    101
2    102
3    103
4    104
5    105
6    106
7    107
8    108
9    109
dtype: int32
In [38]: print(s2.index)
RangeIndex(start=0, stop=10, step=1)

序列默认使用从0开始以步长1自增的索引,我们还可以自己更改索引值

In [40]: s2.index = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
In [41]: print(s2)
a    100
b    101
c    102
d    103
e    104
f    105
g    106
h    107
i    108
j    109
dtype: int32

这样以来Series就有了NumPy中一维数组的使用方式以及类似于Python中字典的取值方式。需要注意的是更改为非数值索引后用冒号切片时值的区间是前闭后闭的。

In [43]: s2[['a', 'b', 'c']]
Out[43]:
a    100
b    101
c    102
dtype: int32
In [44]: s2['b':'f']
Out[44]:
b    101
c    102
d    103
e    104
f    105
dtype: int32
自动对齐

如果我们想将两个序列的值按照一定位置进行两两运算,那么索引这时候就派上大用场了。Series对象在进行算数运算时会将元素按照索引顺序进行运算

In [81]: s3 = pd.Series(np.arange(10,15), index = ['a', 'b', 'c', 'd', 'e'])
In [82]: s4 = pd.Series(np.arange(0,500,step=100), index = ['d', 'c', 'a', 'e', 'f'])
In [83]: print(s3, s4)
a    10
b    11
c    12
d    13
e    14
dtype: int32 
d      0
c    100
a    200
e    300
f    400
dtype: int32
In [84]: print(s3 + s4)
a    210
b    NaN
c    112
d     13
e    314
f     NaN
dtype: int32

由于部分索引只存在于一个序列中,所以在进行运算时会把该索引位置的值置为NaN。对于DataFrame,不仅仅是行索引的对齐,同时还会对列索引进行对齐,下面会进行说明。

pandas查询数据

DataFrame对象有类似表格的输出格式,我们可以通过行或列进行内容选取。下面录入一些学生的基本信息

In [88]: stu_dic = {'Age':[14,13,13,14,14,12,12,15,13,12,11,14,12,15,16,12,15,11,15],
    ...: 'Height':[69,56.5,65.3,62.8,63.5,57.3,59.8,62.5,62.5,59,51.3,64.3,56.3,66.5,72,64.
    ...: 8,67,57.5,66.5],
    ...: 'Name':['Alfred','Alice','Barbara','Carol','Henry','James','Jane','Janet','Jeffrey
    ...: ','John','Joyce','Judy','Louise','Marry','Philip','Robert','Ronald','Thomas','Will
    ...: am'],
    ...: 'Gender':['M','F','F','F','M','M','F','F','M','M','F','F','F','F','M','M','M','M',
    ...: 'M'],
    ...: 'Weight':[112.5,84,98,102.5,102.5,83,84.5,112.5,84,99.5,50.5,90,77,112,150,128,133
    ...: ,85,112]}
In [89]: student = pd.DataFrame(stu_dic)
In [90]: print(student)
    Age Gender  Height     Name  Weight
0    14      M    69.0   Alfred   112.5
1    13      F    56.5    Alice    84.0
2    13      F    65.3  Barbara    98.0
3    14      F    62.8    Carol   102.5
4    14      M    63.5    Henry   102.5
5    12      M    57.3    James    83.0
6    12      F    59.8     Jane    84.5
7    15      F    62.5    Janet   112.5
8    13      M    62.5  Jeffrey    84.0
9    12      M    59.0     John    99.5
10   11      F    51.3    Joyce    50.5
11   14      F    64.3     Judy    90.0
12   12      F    56.3   Louise    77.0
13   15      F    66.5    Marry   112.0
14   16      M    72.0   Philip   150.0
15   12      M    64.8   Robert   128.0
16   15      M    67.0   Ronald   133.0
17   11      M    57.5   Thomas    85.0
18   15      M    66.5   Willam   112.0

head和tail函数可以用来查询前几行或后几行数据(默认查询5行)

In [92]: student.head()
Out[92]:
   Age Gender  Height     Name  Weight
0   14      M    69.0   Alfred   112.5
1   13      F    56.5    Alice    84.0
2   13      F    65.3  Barbara    98.0
3   14      F    62.8    Carol   102.5
4   14      M    63.5    Henry   102.5
In [93]: student.tail(3)
Out[93]:
    Age Gender  Height    Name  Weight
16   15      M    67.0  Ronald   133.0
17   11      M    57.5  Thomas    85.0
18   15      M    66.5  Willam   112.0

查询指定列直接用索引

In [97]: student[['Name', 'Age', 'Gender']].head()
Out[97]:
      Name  Age Gender
0   Alfred   14      M
1    Alice   13      F
2  Barbara   13      F
3    Carol   14      F
4    Henry   14      M

查询指定行的数据用loc位置函数,该函数可以按索引选取数据。类似的iloc函数可以根据位置选取数据

In [96]: student.loc[[1,3,5,7]]
Out[96]:
   Age Gender  Height   Name  Weight
1   13      F    56.5  Alice    84.0
3   14      F    62.8  Carol   102.5
5   12      M    57.3  James    83.0
7   15      F    62.5  Janet   112.5

查询指定行的指定列信息

In [120]: student.loc[1:5, ['Name', 'Age', 'Gender']]
Out[120]:
      Name  Age Gender
1    Alice   13      F
2  Barbara   13      F
3    Carol   14      F
4    Henry   14      M
5    James   12      M

DataFrame用布尔列表作为索引可以进行条件搜索,同理可以在索引处使用逻辑运算。查询所有12岁以上的女生信息

In [127]: student.head()[[True,False,True,False,True]]
Out[127]:
   Age Gender  Height     Name  Weight
0   14      M    69.0   Alfred   112.5
2   13      F    65.3  Barbara    98.0
4   14      M    63.5    Henry   102.5
In [128]: student[(student['Gender']=='F') & (student['Age']>12)]
Out[128]:
    Age Gender  Height     Name  Weight
1    13      F    56.5    Alice    84.0
2    13      F    65.3  Barbara    98.0
3    14      F    62.8    Carol   102.5
7    15      F    62.5    Janet   112.5
11   14      F    64.3     Judy    90.0
13   15      F    66.5    Marry   112.0

利用DataFrame进行统计分析

pandas模块为我们提供了非常多用于统计分析的函数,如求和、均值、最小值、最大值等

In [166]: data = pd.Series(np.random.randn(10))
In [167]: print(data)
0    0.139683
1   -0.223019
2    2.123692
3    0.122273
4   -1.409432
5    1.422986
6   -2.147855
7   -1.347533
8    0.363565
9   -0.014752
dtype: float64
In [168]: print(data.count()) #统计总个数
10
In [169]: print(data.max()) #最大值
2.12369188859
In [170]: print(data.min()) #最小值
-2.14785503764
In [171]: print(data.idxmax()) #最大值的索引
2
In [172]: print(data.idxmin()) #最小值的索引
6
In [173]: print(data.quantile(0.25)) #25%分位数
-1.0664041305639353
In [174]: print(data.sum()) #求和
-0.970391278249
In [175]: print(data.mean()) #平均值
-0.0970391278249
In [176]: print(data.median()) #中位数
0.05376066122711701
In [177]: print(data.mode()) #众数
0   -2.147855
1   -1.409432
2   -1.347533
3   -0.223019
4   -0.014752
5    0.122273
6    0.139683
7    0.363565
8    1.422986
9    2.123692
dtype: float64
In [178]: print(data.var()) #方差
1.67477886567
In [179]: print(data.std()) #标准差
1.29413247609
In [180]: print(data.mad()) #平均绝对差
0.947936352321
In [181]: print(data.skew()) #偏度
0.111671093612
In [182]: print(data.kurt()) #峰度
-0.229936797723
In [183]: print(data.describe()) #一次性输出多个描述性统计指标
count    10.000000
mean     -0.097039
std       1.294132
min      -2.147855
25%      -1.066404
50%       0.053761
75%       0.307594
max       2.123692
dtype: float64
In [184]: print(data.value_counts())  # 查看Series对象的唯一zhi和计数

有时我们需要将一个函数应用到DataFrame中的每一列当中,这时可以借助apply函数

In [198]: print(d1)
[ 1.35779726 -0.80483372 -2.12362025 -0.33350244 -0.88671935  0.33419793
  0.53678382 -0.74383037 -0.32020388 -0.91619886]
In [199]: d2 = np.random.f(2,4,size=10)
In [200]: print(d2)
[ 1.9737911   2.58048514  0.77602181  3.20355989  1.34335165  0.64734569
  0.52191629  0.56962343  5.23736555  0.14573449]
In [201]: d3 = np.random.randint(50,100,size=10)
In [202]: print(d3)
[76 65 56 88 88 70 67 66 73 70]
In [203]: df = pd.DataFrame(np.array([d1,d2,d3]).T, columns=['x1', 'x2', 'x3'])
In [204]: print(df.head())
         x1        x2    x3
0  1.357797  1.973791  76.0
1 -0.804834  2.580485  65.0
2 -2.123620  0.776022  56.0
3 -0.333502  3.203560  88.0
4 -0.886719  1.343352  88.0
In [209]: print(df.apply(lambda x: x.describe()))
              x1         x2         x3
count  10.000000  10.000000  10.000000
mean   -0.390013   1.699920  71.900000
std     0.958737   1.591444  10.016098
min    -2.123620   0.145734  56.000000
25%    -0.866248   0.589054  66.250000
50%    -0.538666   1.059687  70.000000
75%     0.170597   2.428812  75.250000
max     1.357797   5.237366  88.000000

在统计离散数据时就不能使用这种统计方式了,我们需要统计离散变量的观测数量、取值种类数、众数及其个数。这时只需要使用describe方法就可以实现

In [211]: print(student['Gender'].describe())
count     19
unique     2
top        M
freq      10
Name: Gender, dtype: object

除了以上简单描述性统计之外,还提供了连续变量的相关系数(corr)和协方差矩阵(cov)的求解。关于相关系数的计算可以调用pearson方法或kendell方法或spearman方法,默认用pearson方法

In [214]: print(df.corr())
          x1        x2        x3
x1  1.000000  0.115625  0.321113
x2  0.115625  1.000000  0.344972
x3  0.321113  0.344972  1.000000

如果只想管制某一个变量与其余变量的相关系数的话,可以使用corrwith,如下方只关心x1与其余变量的相关系数

In [216]: print(df.corrwith(df['x1']))
x1    1.000000
x2    0.115625
x3    0.321113
dtype: float64

利用Pandas实现SQL操作

在SQL中常见的操作主要是增、删、改、查,在Pandas中同样可以实现这几项操作。新增数据操作对新数据的格式要求十分少,即使列值对不上也会自行新增列,列名顺序不一致也会自动进行对齐

In [226]: dic = {'Name':['LiuShunxiang','Zhangshan'],'Gender':['M','F'],'Age':[27,23],'Heig
     ...: ht':[165.7,167.2],'Weight':[61,63]}
In [227]: student1 = pd.DataFrame(dic)
In [228]: student2 = pd.concat([student.head(), student1])
In [229]: print(student2)
   Age Gender  Height          Name  Weight
0   14      M    69.0        Alfred   112.5
1   13      F    56.5         Alice    84.0
2   13      F    65.3       Barbara    98.0
3   14      F    62.8         Carol   102.5
4   14      M    63.5         Henry   102.5
0   27      M   165.7  LiuShunxiang    61.0
1   23      F   167.2     Zhangshan    63.0

新增列后,默认将新列上的值都赋为NaN

In [230]: print(pd.DataFrame(student2, columns
=['Age','Height','Name','Gender','Weight','Score']))
   Age  Height          Name Gender  Weight  Score
0   14    69.0        Alfred      M   112.5    NaN
1   13    56.5         Alice      F    84.0    NaN
2   13    65.3       Barbara      F    98.0    NaN
3   14    62.8         Carol      F   102.5    NaN
4   14    63.5         Henry      M   102.5    NaN
0   27   165.7  LiuShunxiang      M    61.0    NaN
1   23   167.2     Zhangshan      F    63.0    NaN

删除DataFrame(可以看成是删除表)使用Python的del关键字。删除整列或整行都使用drop函数,使用drop函数时需要指定轴axis,默认为0即代表着行(条件删除可以使用索引条件过滤然后复制给当前DataFrame)

In [260]: del student1
In [261]: print(student2.drop([1,3,5]))
   Age Gender  Height       Name  Weight
0   14      M    69.0     Alfred   112.5
2   13      F    65.3    Barbara    98.0
4   14      M    63.5      Henry   102.5
6   23      F   167.2  Zhangshan    63.0
In [262]: print(student2.drop(['Height', 'Weight'], axis=1).head())
   Age Gender     Name
0   14      M   Alfred
1   13      F    Alice
2   13      F  Barbara
3   14      F    Carol
4   14      M    Henry

可以使用布尔索引结合赋值的方法

In [274]: student2.loc[student2['Name']=='Alfred', 'Height'] = 173
In [275]: student2.loc[student2['Name']=='Alfred']
Out[275]:
   Age Gender  Height    Name  Weight
0   14      M   173.0  Alfred   112.5

上面已经讲过,不做赘述

聚合

Pandas中可以通过groupby函数实现数据的聚合操作,通过值将观测行分组

In [277]: print(student.groupby('Gender').mean())  # 统计男女的各项平均值
              Age     Height      Weight
Gender
F       13.222222  60.588889   90.111111
M       13.400000  63.910000  108.950000

如果不想将某个值做统计,可以先用drop删除列然后做groupby操作。还可以用agg函数对分组计算多个统计量

In [279]: print(student.drop('Age',axis=1).groupby('Gender').agg([np.mean, np.median]))
           Height             Weight
             mean median        mean  median
Gender
F       60.588889  62.50   90.111111   90.00
M       63.910000  64.15  108.950000  107.25
排序

排序在日常的统计分析中比较常见,我们可以使用sort_index和sort_values函数对Series或DataFrame对象实现按值排序和按索引排序,ascending=True/False可以指定使用升序还是降序

In [293]: print(student.head())
   Age Gender  Height     Name  Weight
0   14      M    69.0   Alfred   112.5
1   13      F    56.5    Alice    84.0
2   13      F    65.3  Barbara    98.0
3   14      F    62.8    Carol   102.5
4   14      M    63.5    Henry   102.5
In [294]: print(student.head().sort_values('Height'))
   Age Gender  Height     Name  Weight
1   13      F    56.5    Alice    84.0
3   14      F    62.8    Carol   102.5
4   14      M    63.5    Henry   102.5
2   13      F    65.3  Barbara    98.0
0   14      M    69.0   Alfred   112.5
In [295]: print(student.head().sort_values(by='Height').sort_index())
   Age Gender  Height     Name  Weight
0   14      M    69.0   Alfred   112.5
1   13      F    56.5    Alice    84.0
2   13      F    65.3  Barbara    98.0
3   14      F    62.8    Carol   102.5
4   14      M    63.5    Henry   102.5
多表连接

Pandas同样于MySQL,分成左右内外连接,用merge函数实现

In [296]: dic2 = {'Name':['Alfred','Alice','Barbara','Carol','Henry','Jeffrey','Judy','Phil
     ...: ip','Robert','Willam'], 'Score':[88,76,89,67,79,90,92,86,73,77]}
In [297]: score = pd.DataFrame(dic2)
In [298]: stu_score1 = pd.merge(student, score, on='Name')  # on指定连接依据
In [299]: print(stu_score1)
   Age Gender  Height     Name  Weight  Score
0   14      M    69.0   Alfred   112.5     88
1   13      F    56.5    Alice    84.0     76
2   13      F    65.3  Barbara    98.0     89
3   14      F    62.8    Carol   102.5     67
4   14      M    63.5    Henry   102.5     79
5   13      M    62.5  Jeffrey    84.0     90
6   14      F    64.3     Judy    90.0     92
7   16      M    72.0   Philip   150.0     86
8   12      M    64.8   Robert   128.0     73
9   15      M    66.5   Willam   112.0     77

merge函数默认使用的是内连接,返回两张表中共同存在的行。你还可以通过how参数设置left、right、outer连接方式,左连接保留前一张表的所有行,右链接保留后一张表的所有行,不存在的值自动设为NaN。

In [306]: score = pd.merge(student,score,how='left').head(10)
In [307]: score
Out[307]:
    Age Gender  Height     Name  Weight  Score
0    14      M    69.0   Alfred   112.5   88.0
1    13      F    56.5    Alice    84.0   76.0
2    13      F    65.3  Barbara    98.0   89.0
3    14      F    62.8    Carol   102.5   67.0
4    14      M    63.5    Henry   102.5   79.0
5    12      M    57.3    James    83.0    NaN
6    12      F    59.8     Jane    84.5    NaN
7    15      F    62.5    Janet   112.5    NaN
8    13      M    62.5  Jeffrey    84.0   90.0
9    12      M    59.0     John    99.5    NaN

利用Pandas进行缺失值的处理

工作场景中我们在整理数据时需要面对缺失值处理的场景。常见的缺失值处理的方法分为三种:删除法、填补法和插值法,这里就介绍一些简单的删除法和填补法。在删除法中,dropna函数直接删除含有NaN的行(可用axis=1删除列,thresh=n删除小于n个非空值的行,how=‘all’ 删除所有值都为NaN的那些行)

In [325]: df = pd.DataFrame([[1,1,2],[3,5,np.nan],[13,21,34],[55,np.nan,10],[np.nan,np.nan,
     ...: np.nan],[np.nan,1,2]],columns=('x1','x2','x3'))
In [326]: print(df)
     x1    x2    x3
0   1.0   1.0   2.0
1   3.0   5.0   NaN
2  13.0  21.0  34.0
3  55.0   NaN  10.0
4   NaN   NaN   NaN
5   NaN   1.0   2.0
In [327]: print(df.dropna()) 
     x1    x2    x3
0   1.0   1.0   2.0
2  13.0  21.0  34.0
In [328]: print(df.dropna(how='all'))
     x1    x2    x3
0   1.0   1.0   2.0
1   3.0   5.0   NaN
2  13.0  21.0  34.0
3  55.0   NaN  10.0
5   NaN   1.0   2.0

填补缺失值可以使用fillna函数,它可以用值替换NaN,也可以用 method='ffill'或'bfill' 来指定用前向或后项填充。但是在大部分情况下我们会依据情况使用众数、中位数、平均数等中心度量值来填充空白数据。

In [331]: print(df.fillna(0))
     x1    x2    x3
0   1.0   1.0   2.0
1   3.0   5.0   0.0
2  13.0  21.0  34.0
3  55.0   0.0  10.0
4   0.0   0.0   0.0
5   0.0   1.0   2.0
In [332]: print(df.fillna(method='ffill'))
     x1    x2    x3
0   1.0   1.0   2.0
1   3.0   5.0   2.0
2  13.0  21.0  34.0
3  55.0  21.0  10.0
4  55.0  21.0  10.0
5  55.0   1.0   2.0
In [333]: print(df.fillna(method='bfill'))
     x1    x2    x3
0   1.0   1.0   2.0
1   3.0   5.0  34.0
2  13.0  21.0  34.0
3  55.0   1.0  10.0
4   NaN   1.0   2.0
5   NaN   1.0   2.0
In [334]: print(df.fillna({'x1':1, 'x2':2, 'x3':3}))
     x1    x2    x3
0   1.0   1.0   2.0
1   3.0   5.0   3.0
2  13.0  21.0  34.0
3  55.0   2.0  10.0
4   1.0   2.0   3.0
5   1.0   1.0   2.0

isnull(和notnull)函数可以检查DataFrame对象中的空(非空)值,返回一个布尔数组

In [358]: print(df.isnull())
      x1     x2     x3
0  False  False  False
1  False  False   True
2  False  False  False
3  False   True  False
4   True   True   True
5   True  False  False

重命名DataFrame对象的列名用columns属性,批量更改类名用rename

In [361]: df
Out[361]:
     x1    x2    x3
0   1.0   1.0   2.0
1   3.0   5.0   NaN
2  13.0  21.0  34.0
3  55.0   NaN  10.0
4   NaN   NaN   NaN
5   NaN   1.0   2.0
In [362]: df.columns = ['a', 'b', 'c']
In [363]: df
Out[363]:
      a     b     c
0   1.0   1.0   2.0
1   3.0   5.0   NaN
2  13.0  21.0  34.0
3  55.0   NaN  10.0
4   NaN   NaN   NaN
5   NaN   1.0   2.0
In [364]: df.rename(columns={'a':'aa'})
Out[364]:
     aa     b     c
0   1.0   1.0   2.0
1   3.0   5.0   NaN
2  13.0  21.0  34.0
3  55.0   NaN  10.0
4   NaN   NaN   NaN
5   NaN   1.0   2.0

在Series对象中替换值使用replace函数

In [359]: s
Out[359]:
a    0
b    1
c    2
d    3
dtype: int32
In [360]: print(s.replace(1, 11))
a     0
b    11
c     2
d     3
dtype: int32

利用Pandas实现Excel的数据透视表

Pandas提供了实现数据透视表功能的pivot_table函数,通过该函数可以直观查看数据的聚合(计数、求和、均值、标准差)情况。该函数可传递的参数有以下这些pivot_table(data,values=None, # values指定需要聚合的字段
index=None, # 指定某些原始变量作为行索引
columns=None, # 指定哪些离散的分组变量
aggfunc='mean', # 指定相应的聚合函数
fill_value=None, # 使用一个常数替代缺失值,默认不替换
margins=False, # 是否进行性行或列的汇总,默认不汇总
dropna=True, # 默认所有观测为缺失的值
margins_name='All') # 默认行汇总或咧汇总的名称为‘All’
下面举个例子,依据Gender、Age对Height、Weight进行展示

In [336]: table = pd.pivot_table(student, values=['Height', 'Weight'], columns=['Gender','A
     ...: ge'])

In [337]: print(table)
        Gender  Age
Height  F       11      51.300000
                12      58.050000
                13      60.900000
                14      63.550000
                15      64.500000
        M       11      57.500000
                12      60.366667
                13      62.500000
                14      66.250000
                15      66.750000
                16      72.000000
Weight  F       11      50.500000
                12      80.750000
                13      91.000000
                14      96.250000
                15     112.250000
        M       11      85.000000
                12     103.500000
                13      84.000000
                14     107.500000
                15     122.500000
                16     150.000000
dtype: float64

如果想把上述格式变换成更像Excel的堆叠格式可以使用unstack函数即可。

In [338]: table = pd.pivot_table(student, values=['Height', 'Weight'], columns=['Gender','A
     ...: ge']).unstack()
In [339]: print(table)
Age              11          12    13      14      15     16
       Gender
Height F       51.3   58.050000  60.9   63.55   64.50    NaN
       M       57.5   60.366667  62.5   66.25   66.75   72.0
Weight F       50.5   80.750000  91.0   96.25  112.25    NaN
       M       85.0  103.500000  84.0  107.50  122.50  150.0

多层索引的使用

在Pandas中我们可以在一个轴上设置多个索引,类似于Excel的如下形式



设置的原理十分易懂

In [340]: s = pd.Series(np.arange(1,10),index=[["a","a","a","b","b","c","c","d","d"],[1,2,3
     ...: ,1,2,3,1,2,3]])
In [341]: print(s)
a  1    1
   2    2
   3    3
b  1    4
   2    5
c  3    6
   1    7
d  2    8
   3    9
dtype: int32

选取元素时需要用两个索引指定一个下标

In [342]: print(s['a'])
1    1
2    2
3    3
dtype: int32
In [343]: print(s['a', 2])
2

DataFrame的层次化索引也类似

In [344]: data = pd.DataFrame(np.random.randint(0,150,size=(8,12)),
     ...:                columns = pd.MultiIndex.from_product([['模拟考','正式考'],
     ...:                                                    ['数学','语文','英语','物理','
     ...: 化学','生物']]),
     ...:                index = pd.MultiIndex.from_product([['期中','期末'],
     ...:                                                    ['雷军','李斌'],
     ...:                                                   ['测试一','测试二']]))
     ...:
In [345]: print(data)
           模拟考                           正式考
            数学   语文   英语   物理   化学   生物   数学   语文   英语   物理   化学   生
物
期中 雷军 测试一   42   26  120   94   25  141   45   50   94   44   88   74
      测试二   76  105  138   87  125   55   60   15   37   54   79   56
   李斌 测试一    6   53   97   74   46   65    5  130   67  129    3  109
      测试二  108   22   89   13   53   47   12   81   19   53   93  104
期末 雷军 测试一   41  136   14    4   33   53  142   43   28   68   88    7
      测试二   47   84  127   28   17  135  116   31  118   49   27   97
   李斌 测试一   30   43   48   24   15    3   26   71   82  104  125   79
      测试二   50  114   43  123  111  106    5   91   34   76   52   82

数据IO

Pandas支持多种格式数据的读写操作,它们的读函数分别为read_csv、read_table(从限定分隔符的文件中读内容)、read_excel、read_sql、read_json、read_html、read_clipboard(从粘贴板读内容),这些函数所用来操作的文件和数据格式一目了然。文件的写操作有函数to_csv、to_excel、to_sql、to_json这几个。

In [371]: df.to_csv('E:\\a.csv')
In [372]: file_str = pd.read_csv('E:\\a.csv')
In [373]: print(file_str)
   Unnamed: 0     a     b     c
0           0   1.0   1.0   2.0
1           1   3.0   5.0   NaN
2           2  13.0  21.0  34.0
3           3  55.0   NaN  10.0
4           4   NaN   NaN   NaN
5           5   NaN   1.0   2.0
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,914评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,935评论 2 383
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,531评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,309评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,381评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,730评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,882评论 3 404
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,643评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,095评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,448评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,566评论 1 339
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,253评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,829评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,715评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,945评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,248评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,440评论 2 348

推荐阅读更多精彩内容