Pandas基础之系统入门

第1章 入门知识


  1. 简述:用于操作行列数据,方便地实现各种形式的数据分析;
  2. Pandas最初主要应用于金融数据分析工作,其为时间序列分析提供了很好的支持;
  3. Pandas的名称来自于面板数据(panel data)和Python数据分析(data analysis)
  4. panel data是经济学中关于多维数据集的一个术语,在Pandas中也提供了panel的数据类型(新版本已停用);
  5. 适用的数据类型
  • 具有异构类型列的表格数据,如SQL表格或Excel数据;
  • 有序和无序(不一定是固定频率)时间序列数据;
  • 具有行列标签的任意矩阵数据(均匀类型或不同类型);
  • 任何其他形式的观测/统计数据集。


第2章 数据结构


  1. 作为一个python库,python中的数据类型在pandas中依然适用
  2. 核心数据结构
  • Series:一维、带有索引、同类型元素的数组,与Numpy中的一维array类似;
  • DateFrame:二维、带有索引、大小可变、可以不同类型元素的表格数据,可以看作是Series的容器,即一个DateFrame可以包含若干个Series

第3章 创建对象


  1. Series:标量值列表,默认索引为整数;
    pd.Series([1, 3, 5, np.nan, 6, 8])
    0    1.0
    1    3.0
    2    5.0
    3    NaN
    4    6.0
    5    8.0
    dtype: float64
    
  2. Dataframe:带有日期时间的索引、Numpy数组;
    dates = pd.date_range('2018-07-10', periods=6)
    
    dates
    -- > DatetimeIndex(['2018-07-10', '2018-07-11', '2018-07-12', '2018-07-13','2018-07-14', '2018-07-15'],
                        dtype='datetime64[ns]', freq='D')
    
    df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list('ABCD'))
    
    print(df) 
                   A            B           C           D
    2018-07-10  -0.710755   -0.757183   0.809279    -0.718210
    2018-07-11  -1.508561   -0.173393   0.815395    -1.242897
    2018-07-12  -2.157823   -0.462607   -0.915480   2.595037
    2018-07-13  0.826433    -0.216765   -1.636825   -0.671588
    2018-07-14  -0.438337   0.270277    -1.208112   1.982913
    2018-07-15  0.863050    0.442406    0.871964    1.107883
    
  3. Dataframe:可以转换为类似Series系列的dict对象;
    df2 = pd.DataFrame({
                    'A':1.,
                    'B':pd.Timestamp('20180710'),
                    'C':pd.Series(1, index=list(range(4)), dtype='float32'),
                    'D':np.array([2]*4, dtype='int32'),
                    'E':np.array([1, 2, 3, 4], dtype='int64'),
                    'F':pd.Categorical(['test', 'learn', 'test', 'learn']),
                    'G':'xz'
                    })  
    
    print(df2)
        A   B           C   D   E   F       G
    0   1.0 2018-07-10  1.0 2   1   test    xz
    1   1.0 2018-07-10  1.0 2   2   learn   xz
    2   1.0 2018-07-10  1.0 2   3   test    xz
    3   1.0 2018-07-10  1.0 2   4   learn   xz
    
  4. DataFrame的不同列,具有不同的dtypes
    print(df2.dtypes)
    
    A           float64
    B    datetime64[ns]
    C           float32
    D             int32
    E             int64
    F          category
    G            object
    dtype: object
    


第4章 查看数据


  1. head(x)查看顶行数据、tail(x)查看底行数据,x表示查看的行数,默认为5;
    df2.head(2)   #查看顶部2行数据
        A   B           C   D   E   F       G
    0   1   2018-07-10  1   2   1   test    xz
    1   1   2018-07-10  1   2   2   learn   xz
    
    df2.tail(3)  # 查看底部3行数据
        A   B           C   D   E   F       G
    1   1   2018-07-10  1   2   2   learn   xz
    2   1   2018-07-10  1   2   3   test    xz
    3   1   2018-07-10  1   2   4   learn   xz
    
  2. 查看索引、列名称、基础Numpy数据;
    df2.index
    -- > Int64Index([0, 1, 2, 3], dtype='int64')
    
    df2.columns
    -- > Index(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype='object')
    
    df2.values
    array([[1.0, Timestamp('2018-07-10 00:00:00'), 1.0, 2, 1, 'test', 'xz'],
           [1.0, Timestamp('2018-07-10 00:00:00'), 1.0, 2, 2, 'learn', 'xz'],
           [1.0, Timestamp('2018-07-10 00:00:00'), 1.0, 2, 3, 'test', 'xz'],
           [1.0, Timestamp('2018-07-10 00:00:00'), 1.0, 2, 4, 'learn', 'xz']], dtype=object)
    
  3. 描述性统计;
    df.describe()
                A           B           C           D
    count   6.000000    6.000000    6.000000    6.000000
    mean    -0.203846   -0.520712   0.252811    0.056574
    std     1.824972    0.629551    1.047736    0.535639
    min     -2.441260   -1.616401   -0.849088   -0.795480
    25%     -1.805976   -0.669989   -0.564042   -0.165330
    50%     0.214104    -0.472665   0.257587    0.142493
    75%     1.160094    -0.065817   0.595098    0.291087
    max     1.793887    0.103427    1.981094    0.777256
    
  4. 转置数据
    df2.T
        0   1   2   3
    A   1   1   1   1
    B   2018-07-10 00:00:00 2018-07-10 00:00:00 2018-07-10 00:00:00 2018-07-10 00:00:00
    C   1   1   1   1
    D   2   2   2   2
    E   1   2   3   4
    F   test    learn   test    learn
    G   xz  xz  xz  xz
    


第5章 选取数据


  1. 获取一列,即Series
    df.A  # 等同于 df['A']
    2018-07-10   -0.177312
    2018-07-11   -2.441260
    2018-07-12   -2.348864
    2018-07-13    0.605520
    2018-07-14    1.344952
    2018-07-15    1.793887
    Freq: D, Name: A, dtype: float64    
    
  2. 行切片:索引或值
    df[:3]  # 索引切片
                    A           B           C           D
    2018-07-10  -0.710755   -0.757183   0.809279    -0.718210
    2018-07-11  -1.508561   -0.173393   0.815395    -1.242897
    2018-07-12  -2.157823   -0.462607   -0.915480   2.595037
    
    df['2018-07-11':'2018-07-14']  # 值切片
                    A            B          C           D
    2018-07-11  -1.508561   -0.173393   0.815395    -1.242897
    2018-07-12  -2.157823   -0.462607   -0.915480   2.595037
    2018-07-13  0.826433    -0.216765   -1.636825   -0.671588
    2018-07-14  -0.438337   0.270277    -1.208112   1.982913
    
  3. 函数:loc[]、iloc[]
  • loc[]:根据行或列的索引值,获取数据,含下限,可仅取行或列;
  • iloc[]:根据行或列的索引位置,获取数据,不含下限,可仅取行或列;
  • 仅取一行
    df.loc['2018-07-11']    等同于    df.iloc[1]
    
    A   -1.508561
    B   -0.173393
    C    0.815395
    D   -1.242897
    Name: 2018-07-11 00:00:00, dtype: float64
    
  • 仅取一列
    df.loc[:,'C']     等同于    df.iloc[:,2] 
    
    2018-07-10    0.809279
    2018-07-11    0.815395
    2018-07-12   -0.915480
    2018-07-13   -1.636825
    2018-07-14   -1.208112
    2018-07-15    0.871964
    Freq: D, Name: C, dtype: float64
    
  • 行列连续截取
    df.loc['2018-07-12':'2018-07-14',['B', 'C', 'D']]    等同于    df.iloc[2:5, 1:4]
    
                    B             C         D
    2018-07-12  -0.462607   -0.915480   2.595037
    2018-07-13  -0.216765   -1.636825   -0.671588
    2018-07-14  0.270277    -1.208112   1.982913
    
    说明:loc[]在选取行索引值时,可以类似切片的形式,但是在选取列索引时,只能一个一个列举,不能像类似切片的形式用冒号连接取连续的中间值。
    
  • 行列不连续截取
    df.iloc[[0,5],[0,3]]   # iloc[]行列均可以不连续截取数据
                    A           D
    2018-07-10  -0.710755   -0.718210
    2018-07-15  0.863050    1.107883
        
    
    df.loc['2017-07-10':'2018-07-15', ['A', 'D']]  # loc[]行索引  不  可以不连续截取
                    A           D
    2018-07-10  -0.710755   -0.718210
    2018-07-11  -1.508561   -1.242897
    2018-07-12  -2.157823   2.595037
    2018-07-13  0.826433    -0.671588
    2018-07-14  -0.438337   1.982913
    2018-07-15  0.863050    1.107883
    
  • 获取单个值
    df.loc['2018-07-14', 'C']    等同于    df.iloc[4,2]
    -1.2081117496772031
    
  • 补充loc[]、iloc[]方法也可以对DataFrame进行赋值等操作。
  1. 布尔判断:多列值判断时,&表示and的关系,|表示or的关系
    df[df.C < 0.5]    #单个列值判断
                    A           B           C           D
    2018-07-12  -2.157823   -0.462607   -0.915480   2.595037
    2018-07-13  0.826433    -0.216765   -1.636825   -0.671588
    2018-07-14  -0.438337   0.270277    -1.208112   1.982913
    
    df[(df.A < 0) & (df.D > 0)]  
                    A           B           C          D
    2018-07-12  -2.157823   -0.462607   -0.915480   2.595037
    2018-07-14  -0.438337   0.270277    -1.208112   1.982913
    
    df[df > 0]  #DataFrame值判断
                  A  B      C        D
    2018-07-10  NaN NaN 0.809279    NaN
    2018-07-11  NaN NaN 0.815395    NaN
    2018-07-12  NaN NaN NaN 2.595037
    2018-07-13  0.826433    NaN NaN NaN
    2018-07-14  NaN 0.270277    NaN 1.982913
    2018-07-15  0.863050    0.442406    0.871964    1.107883
    
  2. 过滤函数:isin()
    df2 = df.copy()
    df2['E'] = ['one', 'two', 'three', 'four', 'five', 'six']
    print(df2)
                    A         B         C         D        E
    2018-07-10 -0.710755 -0.757183  0.809279 -0.718210    one
    2018-07-11 -1.508561 -0.173393  0.815395 -1.242897    two
    2018-07-12 -2.157823 -0.462607 -0.915480  2.595037  three
    2018-07-13  0.826433 -0.216765 -1.636825 -0.671588   four
    2018-07-14 -0.438337  0.270277 -1.208112  1.982913   five
    2018-07-15  0.863050  0.442406  0.871964  1.107883    six
    
    df2[df2.E.isin(['two', 'five'])]
                    A           B           C           D       E
    2018-07-11  -1.508561   -0.173393   0.815395    -1.242897   two
    2018-07-14  -0.438337   0.270277    -1.208112   1.982913    five
    
  3. 模糊匹配:contains()
    df2[df2.E.str.contains('o')]  # 选取E列中含有关键字“o”的数据
                    A           B           C           D       E
    2018-07-10  -1.738617   -1.013051   -1.938631   -1.049786   one
    2018-07-11  -0.719089   -1.042707   -0.616299   0.460417    two
    2018-07-13  -0.446243   -2.036736   1.469567    0.256282    four
    
  4. 获取数据的方法,同样可以对DataFrame进行重新赋值。

第6章 缺失值


  1. Pandas使用np.nan来表示缺失的数据,默认不包含在计算中;
  2. 准备数据
    df3 = df.reindex(index=dates[0:4], columns=list(df.columns) + ['E'])  # 增加索引,默认数据均为空
    df3.iloc[0:2, 4] = 1  # 赋值
    print(df3)
                   A         B         C         D       E
    2018-07-10 -0.177312 -0.456757 -0.849088  0.107067   1
    2018-07-11 -2.441260 -0.730461  1.981094  0.177919   1
    2018-07-12 -2.348864  0.103427  0.607445 -0.795480 NaN
    2018-07-13  0.605520 -0.488574  0.558058  0.328810 NaN
    
  3. 删除任何缺少数据的行
    df3.dropna(how='any')  # axis=1时删除列数据、how=all时所有值均为空时才删除
                    A           B           C           D       E
    2018-07-10  -0.710755   -0.757183   0.809279    -0.718210   1.0
    2018-07-11  -1.508561   -0.173393   0.815395    -1.242897   1.0
    
  4. 替换缺失值
    df3.fillna(1000)   #将空值替换为1000
                    A           B           C           D       E
    2018-07-10  -0.710755   -0.757183   0.809279    -0.718210   1.0
    2018-07-11  -1.508561   -0.173393   0.815395    -1.242897   1.0
    2018-07-12  -2.157823   -0.462607   -0.915480   2.595037    1000.0
    2018-07-13  0.826433    -0.216765   -1.636825   -0.671588   1000.0
    
  5. 判断缺失值
    pd.isna(df3) # 不同的pandas版本,可以用isnull()
                  A       B       C       D      E
    2018-07-10  False   False   False   False   False
    2018-07-11  False   False   False   False   False
    2018-07-12  False   False   False   False   True
    2018-07-13  False   False   False   False   True
    


第7章 排序


  1. 按索引排序
  • 语法:sort_index(axis=0/1, ascengding=True/False)
  • axis缺失或为0时,按行索引排序,为1时按列索引(columns)排序;
  • ascengding缺失或为True时,表示升序,为False时表示降序;
  • 示例
    df3.sort_index(axis=1, ascending=False)  #列排序,降序
                 E      D          C            B           A
    2018-07-10  1.0 -0.718210   0.809279    -0.757183   -0.710755
    2018-07-11  1.0 -1.242897   0.815395    -0.173393   -1.508561
    2018-07-12  NaN 2.595037    -0.915480   -0.462607   -2.157823
    2018-07-13  NaN -0.671588   -1.636825   -0.216765   0.826433
    
  1. 按值排序
  • 语法:sort_values(by='colums_name', ascengding=True/False)
  • 示例
    df3.sort_values(by=['D', 'C'], ascending=False)
                    A           B           C           D       E
    2018-07-12  -2.157823   -0.462607   -0.915480   2.595037    NaN
    2018-07-13  0.826433    -0.216765   -1.636825   -0.671588   NaN
    2018-07-10  -0.710755   -0.757183   0.809279    -0.718210   1.0
    2018-07-11  -1.508561   -0.173393   0.815395    -1.242897   1.0
    
  1. 自定义排序
  • 步骤
    • 第一步:将需要自定义排序的字段,设置为“category”数据类型
    • 第二步:对字段进行自定义排序
    • 第三步:对DataFrame进行排序
  • 准备数据
    df_sort = pd.DataFrame({
        "word":['a', 'b', 'c'],
        "number":[1, 2, 3]})
    
    print(df_sort)
    word    number
    0   a   1
    1   b   2
    2   c   3
    
    # 需要排列的顺序
    sort_column = ['c', 'b', 'a'] 
    
  • 示例
    df_sort.word = df.word.astype('category')  #把排序字段设置为"category"类型
    df_sort.word.cat.reorder_categories(sort_column, inplace=True)   # 字段按自定义排序
    df_sort.sort_values('word',inplace=True)   # DataFrame按自定义排序
    
    print(df_sort)
      word  number
    2   c   3
    1   b   2
    0   a   1
    


第8章 常用操作


  1. 统计:mean(x)count(x)min(x)max(x)std(x)等,x为0时是行操作、x为1时是列操作。统计时上述函数会忽略缺失值。
    df3.mean()    #统计每列的均值
    A   -0.887676
    B   -0.402487
    C   -0.231908
    D   -0.009415
    E    1.000000
    dtype: float64
    
    df3.max(1)  #统计每行的最大值
    2018-07-10    1.000000
    2018-07-11    1.000000
    2018-07-12    2.595037
    2018-07-13    0.826433
    Freq: D, dtype: float64
    
  2. 函数:apply()
    df3.apply(np.cumsum)  #统计每列的累加和
                    A           B           C           D       E
    2018-07-10  -0.710755   -0.757183   0.809279    -0.718210   1.0
    2018-07-11  -2.219316   -0.930576   1.624674    -1.961108   2.0
    2018-07-12  -4.377138   -1.393183   0.709194    0.633930    NaN
    2018-07-13  -3.550705   -1.609948   -0.927632   -0.037658   NaN
    
    df3.apply(lambda x: x.max() - x.min(), axis=1)  #统计每行最大值与最小值之差
    2018-07-10    1.757183
    2018-07-11    2.508561
    2018-07-12    4.752860
    2018-07-13    2.463258
    Freq: D, dtype: float64
    
  3. 求和、不同值计数
    np.sum(df3.C)    # 对C列求和
    -0.927631569447292
    
    df3.E.value_counts()  # 对E列不同值计数,自动忽略空值
    1.0    2
    Name: E, dtype: int64
    
  4. 字符串方法str
    df4 = pd.DataFrame({"A":['foo', 'bar', 'bar', 'xz'],
                        "B":['one', 'two', 'one', 'two'],
                        "C":['Small', 'Small', 'Large', 'Large'],
                        "D":[1, 2, 3, 4]})
    print(df4)
        A    B    C     D
    0   foo one Small   1
    1   bar two Small   2
    2   bar one Large   3
    3   xz  two Large   4
    
    df4.C.str.lower()  # 字符串转换为 小写
    0    small
    1    small
    2    large
    3    large
    Name: C, dtype: object
    
    df4[df4.A.str.endswith('r')]  #字符串结尾字符筛选
        A   B    C      D
    1   bar two Small   2
    2   bar one Large   3
    


第9章 合并


  1. 关联merge()
  • 用法:通过 横向拼接,类似sql中的join,通过一个或多个键将不同的DataFrame关联
  • 参数说明
    • how : inner、outer、left、right 关联方式
    • on : [key1, key2......] 同字段名关联
    • left_on / right_on 、 left_key / right_key、left_index / right_index 不同字段名关联
    • left_index / right_index = True时,表示按索引进行匹配
  • 多对多关联
    left = pd.DataFrame({'key':['xz', 'xz'], 'value':[1, 2]})
    print(left)
       key  value
    0  xz      1
    1  xz      2
    right = pd.DataFrame({'key':['xz', 'xz'], 'value':[5, 6]})
    print(right)
    key  value
    0  xz      5
    1  xz      6
    
    join = pd.merge(left, right, on='key')   #多对多关联
    print(join)
       key  value_x  value_y
    0  xz        1        5
    1  xz        1        6
    2  xz        2        5
    3  xz        2        6
    
  • 一对一关联
    left = pd.DataFrame({'key':['xz', 'ab'], 'value':[1, 2]})
    print(left)
    key  value
    0  xz      1
    1  ab      2
    right = pd.DataFrame({'key':['xz', 'ab'], 'value':[5, 6]})
    print(right)
    key  value
    0  xz      5
    1  ab      6
    
    join = pd.merge(left, right, on='key')  # 一对一关联
    print(join)
       key  value_x  value_y
    0  xz        1        5
    1  ab        2        6
    
  1. 追加append()
  • 用法:纵向追加数据,横向同时扩充,不考虑columns和index,数据列不一样时,设置ignore_index = True
  • 示例
    df5 = pd.DataFrame(np.random.randint(10, 20, [2,4]),columns=list('ABCD'))
    print(df5) 
        A   B   C   D
    0  19  16  15  15
    1  16  15  16  10
    
    s = df5[1:] 
    print(s)
        A   B   C   D
    1  16  15  16  10
    
    df5.append(s, ignore_index=True)   # ignore_index:默认为False, 若为True,表示不要使用索引标签
        A   B   C   D
    0   19  16  15  15
    1   16  15  16  10
    2   16  15  16  10
    
  1. 拼接concat()
  • 用法:单纯的表拼接,可以横向纵向,可以一次性拼接多个表,结果不去重复,需要指定轴进行连接,drop_duplicates()可以去重复。
  • 参数说明
    • objs :连接对象,如:Series、DataFrame、list
    • axis = 0 时,与append()方法相同;axis = 1时,与merge()方法相同
    • join :inner、outer(默认)
    • join_axes :设置需要保留的表索引
    • ignore_index :是否忽略原索引
    • keys :为原连接对象添加一个键,便于后期分组统计
  • 示例
    df6 = pd.DataFrame(np.random.randn(8, 4))
    print(df6)
           0         1         2         3
    0  1.259128  1.352209  0.934947  0.734223
    1 -0.567591 -1.114880 -1.540007  0.192176
    2  1.007433  0.774980  1.229243  1.413190
    3  1.029385  0.316052  0.363644  1.310764
    4 -0.414858  2.030369  1.910180 -0.785533
    5  0.684923 -0.064547 -1.475371 -0.842338
    6 -0.289478  2.119747  0.519206 -2.564895
    7  0.958962 -1.278468  0.099762  0.226029
    
    pd.concat([df6[:2], df6[3:5], df6[7:]], keys=['x', 'y', 'z'])
               0            1           2           3
    x   0   1.259128    1.352209    0.934947    0.734223
        1   -0.567591   -1.114880   -1.540007   0.192176
    y   3   1.029385    0.316052    0.363644    1.310764
        4   -0.414858   2.030369    1.910180    -0.785533
    z   7   0.958962    -1.278468   0.099762    0.226029
    
  1. 合并join()
  • 用法:默认以index为拼接列,其参数与merge方法基本一致,默认 how = left ,可以合并相同或相似的索引,目前已较少使用。

第10章 分组


  1. 列分组--列运算

    df7 = pd.DataFrame({'A': list('XYZXYZXYZX'), 
                       'B': [1, 2, 1, 3, 1, 2, 3, 3, 1, 2], 
                       'C': [12, 14, 11, 12, 13, 14, 16, 12, 10, 19]})
    print(df7)
        A   B   C
    0   X   1   12
    1   Y   2   14
    2   Z   1   11
    3   X   3   12
    4   Y   1   13
    5   Z   2   14
    6   X   3   16
    7   Y   3   12
    8   Z   1   10
    9   X   2   19
    
    df7.groupby('A').C.mean()  # 按A列分组,统计C列的均值
    A
    X    14.750000
    Y    13.000000
    Z    11.666667
    Name: C, dtype: float64
    
  2. 列分组--多种运算

    df7.groupby('A').B.agg([np.mean,np.std])
           mean     std
    A       
    X   2.250000    0.957427
    Y   2.000000    1.000000
    Z   1.333333    0.577350
    
  3. 列分组--相同运算

    df7.groupby('A')['B', 'C'].mean()
            B           C
    A       
    X   2.250000    14.750000
    Y   2.000000    13.000000
    Z   1.333333    11.666667
    
  4. 列分组--不同运算

    df7.groupby('A')['B', 'C'].agg({'B': 'count', 'C': 'sum'})  
        B   C
    A       
    X   4   59
    Y   3   39
    Z   3   35
    说明:在分组统计时,一般的统计函数会自动忽略空值,计数时使用`size()`函数,会包含空值。
    
  5. 列分组--多个不同运算

    df7.groupby('A').agg({'B':[np.mean, 'sum'], 'C':['count', np.std]}) 
           B            C
          mean    sum  count  std
    A               
    X   2.250000    9   4   3.403430
    Y   2.000000    6   3   1.000000
    Z   1.333333    4   3   2.081666
    
  6. 列分组--列运算

    df7.groupby(['A', 'B']).C.sum()
    A  B
    X  1    12
       2    19
       3    28
    Y  1    13
       2    14
       3    12
    Z  1    21
       2    14
    
    说明:多列分组后的各种运算,和单列分组后一样,不再举例。
    
  7. 函数apply()+lambda()

    df7.groupby('A').apply(lambda x: (x['C'] - x['B']).mean())  # B列与C列之差的均值
         A
    X    12.500000
    Y    11.000000
    Z    10.333333
    
  8. 函数transform()

  • 聚合运算时,通常输出的结果是一个以分组名为 index 的结果对象,若需要使用原数组的 index ,即把聚合结果关联到原数组对象时,使用该函数。
  • 示例
    # 普通的分组
    df7.groupby(['A', 'B']).C.count()
    A  B
    X  1    1
       2    1
       3    2
    Y  1    1
       2    1
       3    1
    Z  1    2
       2    1
    
    df7['count'] = df7.groupby(['A', 'B']).C.transform('count')
    print(df7)
        A   B   C  count
    0   X   1   12  1
    1   Y   2   14  1
    2   Z   1   11  2
    3   X   3   12  2
    4   Y   1   13  1
    5   Z   2   14  1
    6   X   3   16  2
    7   Y   3   12  1
    8   Z   1   10  2
    9   X   2   19  1
    
  1. 分段分组
  • 分段函数cut():将数据值分段,主要用于将连续变量转换为分类变量
  • 等距离分段:数据中的最小值和最大值,左右侧各扩展0.1%,做为分段边界;
    df8 = pd.DataFrame({'Age': np.random.randint(20, 70, 15), 
                       'Sex': np.random.choice(['Male', 'Female'], 15), 
                       'num': np.random.randint(1, 20, 15)}) 
    print(df8)
        Age Sex   num
    0   22  Male    6
    1   49  Male    12
    2   52  Female  13
    3   29  Female  1
    4   46  Male    18
    5   64  Female  2
    6   42  Male    9
    7   33  Male    15
    8   25  Male    16
    9   38  Male    4
    10  32  Male    8
    11  28  Male    8
    12  31  Male    8
    13  62  Male    6
    14  40  Male    13
    
    pd.cut(df8['Age'], bins=3)  #等距离分割
    0     (21.958, 36.0]
    1       (36.0, 50.0]
    2       (50.0, 64.0]
    3     (21.958, 36.0]
    4       (36.0, 50.0]
    5       (50.0, 64.0]
    6       (36.0, 50.0]
    7     (21.958, 36.0]
    8     (21.958, 36.0]
    9       (36.0, 50.0]
    10    (21.958, 36.0]
    11    (21.958, 36.0]
    12    (21.958, 36.0]
    13      (50.0, 64.0]
    14      (36.0, 50.0]
    Name: Age, dtype: category
    Categories (3, interval[float64]): [(21.958, 36.0] < (36.0, 50.0] < (50.0, 64.0]]
    
    df8.groupby(pd.cut(df8['Age'], bins=3)).mean()  # 等距分组
                        Age     num
    Age     
    (21.958, 36.0]  28.571429   8.857143
    (36.0, 50.0]    43.000000   11.200000
    (50.0, 64.0]    59.333333   7.000000
    
  • 自定义范围分段:范围段可以不均匀
    pd.cut(df8['Age'], bins=[0,30,50,np.inf])  #自定义范围进行分割,可以不均匀
    0      (50.0, inf]
    1      (0.0, 30.0]
    2      (50.0, inf]
    3      (0.0, 30.0]
    4     (30.0, 50.0]
    5      (50.0, inf]
    6      (50.0, inf]
    7     (30.0, 50.0]
    8      (0.0, 30.0]
    9     (30.0, 50.0]
    10     (50.0, inf]
    11     (0.0, 30.0]
    12     (50.0, inf]
    13    (30.0, 50.0]
    14     (50.0, inf]
    Name: Age, dtype: category
    Categories (3, interval[float64]): [(0.0, 30.0] < (30.0, 50.0] < (50.0, inf]]
    
    # 自定义分段进行分组统计
    df8.groupby(pd.cut(df8['Age'], bins=[0, 30, 50, np.inf])).mean()
                      Age         num
    Age     
    (0.0, 30.0]     23.250000   8.250000
    (30.0, 50.0]    37.000000   9.250000
    (50.0, inf]     59.428571   10.428571
    
  1. 统计频率
  • 交叉表crosstab():一种特殊的pivot_table(),主要于计算分段分组频率;
  • 对指定列分段后,再进行分组,经常需要计算分组频率;
  • 对字段Age分段后,计算Sex的分组频率,即按 Age 的分组范围和性别 Sex 进行制作交叉表。
    pd.crosstab(pd.cut(df8.Age, bins=[0, 30, 50, np.inf]), df8.Sex)
    
    Sex         Female  Male
    Age     
    (0.0, 30.0]     1   3
    (30.0, 50.0]    0   8
    (50.0, inf]     2   1
    


第11章 透视表


  1. pivot_table()
  • 参数说明
param instroduction
data DataFrame
value 待聚合的列名称,默认聚合所有数据列
index 用于分组的列名或其他分组键,出现在结果透视表的
columns 用于分组的列名或其他分组键,出现在结果透视表的
aggfunc 聚合函数或函数列表,默认为mean。可以使任何对groupby有效的函数
fill_value 用于替换结果表中的缺失值
dropna boolean,默认为True
margins 是否添加汇总的行列
margins_name 默认为all,margins=True时设置汇总行列的名称
  • 准备数据
    df9 = pd.DataFrame({
        "A": ["foo", "foo", "foo", "foo", "foo","bar", "bar", "bar", "bar"],
        "B": ["one", "one", "one", "two", "two","one", "one", "two", "two"],
        "C": ["small", "large", "large", "small","small", "large", "small", "small","large"],
        "D": [1, 2, 3, 4, 3, 4, 5, 6, 7]})
    print(df9)
        A    B      C   D
    0  foo  one  small  1
    1  foo  one  large  2
    2  foo  one  large  3
    3  foo  two  small  4
    4  foo  two  small  3
    5  bar  one  large  4
    6  bar  one  small  5
    7  bar  two  small  6
    8  bar  two  large  7
    
  • 默认聚合方法
    pd.pivot_table(df9, index=['A', 'B'], columns='C', values='D')   #默认聚合函数为均值
    
    C     large small
    A   B       
    bar one 4.0 5.0
        two 7.0 6.0
    foo one 2.5 1.0
        two NaN 3.5
    
  • 设置聚合方法
    # 设置单个聚合方法
    pd.pivot_table(df9, index=['A', 'B'], columns='C', values='D', aggfunc=np.sum, fill_value=0)  #求和、空值设置为0
    
    C     large small
    A   B       
    bar one 4   5
        two 7   6
    foo one 5   1
        two 0   7
    
    # 设置多个聚合方法
    df9['E'] = [8, 9, 10, 11, 12, 13, 14, 15, 16]   
    pd.pivot_table(df13, values=['D', 'E'], index=['A', 'C'],
                                 aggfunc={'D': np.mean,
                                          'E': [min, max, np.median]})
                D          E
                mean      max   median  min
    A   C               
    bar large   5.500000    16  14.5    13
        small   5.500000    15  14.5    14
    foo large   2.500000    10  9.5 9
        small   2.666667    12  11.0    8
    
  1. pivot()
  • 透视后,不进行统计处理,主要用来处理非数字数据,进行行列转换;
  • index只能是一个指定的列,indexcolumns对应的数据元组,不能有重复,否则会报错。
  • 准备数据
    df10 = pd.DataFrame({
        "A": ["foo",  "bar", "bar", "xz"],
        "B": ["one",  "two", "one",  "two"],
        "C": ["small", "large", "large", "small"],
        "D": [1, 2, 3, 4]})
    
    print(df10) 
        A    B      C  D
    0  foo  one  small  1
    1  bar  two  large  2
    2  bar  one  large  3
    3   xz  two  small  4
    
  • 示例
    df10.pivot(index='A', columns='B', values='D')
    B   one two
    A       
    bar 3.0 2.0
    foo 1.0 NaN
    xz  NaN 4.0
    


第12章 其它

  1. 操作文件
  • 以csv格式文件为例,读取read_csv()、写入to_csv()
  • 常见格式:excel、txt、sql、html、json等
  1. 常用操作
  • 查看列的数据类型:df.dtypes
  • 查看数据详情:df.info()
  • 删除A列 : df.drop(A, axis = 1)
  • 更改列名 : df = df.rename(columns = {'old_name': 'new_name'})
  • 替换值 : df.replace(to_replace, values)
  • 设置列数据类型:df.A = df.A.values.astype(‘float64’)
  • 日期字符串转date:pd.to_datetime(df.date).dt.date
  • 日期字符串转时间戳:pd.to_datetime(df.date).dt.to_pydatetime()
  1. 时间处理dt
  • 用途:作用于datetime64[ns]/timedelta64[ns]等日期型数据,获取datetimelike属性的Accessor对象
  • 设置日期格式 : dt.strftime()
  • 获取日期中的信息:dt.date / dt.year / dt.month / dt.time / dt.weekday / dt.dayofyear / dt.weekofyear
  • 设置日期运算单位 : [datetime1 - datetime2].dt.days
  1. 合并列cat
  • 语法:df['A'].str.cat([df['B'], df['C']], sep='-')
  • 合并的2列的内容必须是字符串,如果是数值型则会报错,需要先转换类型;
  • 当需要将某列的内容都加上一个指定字符时,可以先创建一个由该字符组成的临时列,再合并。
  1. DataFrame四则运算
  • add : 加法运算,举例:DataFrame1.add(DataFrame2, fill_value=0)
  • sub : 减法运算,举例:DataFrame1.sub(DataFrame2, fill_value=0)
  • mul : 乘法运算,举例:DataFrame1.mul(DataFrame2)
  • div : 除法运算,举例:DataFrame1.div(DataFrame2)
  • 说明 : 上述参数DataFrame2可以是:Series、DataFrame、constant,Series类型的数据,也有类似如上的四则运算。
  1. 设置显示选项 : pandas.set_option(pat, value)
  • 保留小数点后的n位数:("precision", n)
  • 展示n列:("max_columns", n)
  • 展示n行:("max_rows", n)
  • 绝对值小于n的显示为0:("chop_threshold", n)
  • pd.options.mode.chained_assignment = None :关闭掉copywarning
  • pd.options.display.max_columns = 999 :设置显示的列数
  1. 常见的小坑
  • DataFrame合并一个Series时,会重新排列生成的列顺序,默认按字母顺序。特别是,使用loc[]iloc[]选取的Series,建议,先to_frame().T转成DataFrame后再合并
  • 列中类似:date、datetime、time型的字符串数据,需要转为datetime64[ns]日期数据,如df.date = pd.to_datetime(df.date),才能进行选取:df[df.date == '2018-11-11']
  • 列中datetime64[ns]日期数据,进行大小判断选取数据时,与空值比较,结果为空;
  • 数据列中存在空数据NaN,使用astype()对其数据类型进行转化时,需要先将空数据NaN排除掉,否则函数不起作用。其参数errors只是对无法进行转换类型的数据(非空)进行处理;
  • df[df.condition] = value,即重新赋值时,会报警,解决办法:需要重新copy()一份,即df[df.condition].copy()后,再赋值。
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
  1. groupby分组后,需要统计的字段较多且有条件判断时,使用apply() + lambda + pd.Series()来快速实现;
  2. 在pandas中,没有isnotin函数,可以通过取反的方式实现,取反的方法就是在函数前面加个~。例如:~(df.A == 4) ,等效于 df.A != 4。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容