Pandas基础之常见的坑

坑点集

  • 当数据中含有缺失值、特殊字符时,若使用 astype() 对其数据类型进行转化,需要先将缺失值排除掉,否则函数不起作用。其参数errors只是对无法进行转换类型的数据(非空)进行处理;

  • pd.read_excel列中有空数据时,会强制改变列的数据格式,比如:会把float强制转成了object,可以增加 fillna() 函数;

  • 获取dataframe中的列时,最常见的2种方式:方括号+列名、点 + 列名。点+列的优点:写法比较简洁快速,缺点是如果列名和关键字重复则无法提取,因为点号调用的是对象,python无法判断出名字一样的列名和关键字;

  • 空DataFrame合并一个Series时,会重新排列生成的行顺序,默认按字母顺序。特别是,使用loc[]或iloc[]选取的Series,建议,先 to_frame().T 转成DataFrame后再合并;

  • 列中datetime64[ns]日期数据,进行大小判断选取数据时,与空值比较,结果为空;

  • 对df[df.condition] = value,即重新赋值时,会报警,解决办法:需要重新copy()一份,即 df[df.condition].copy() 后,再赋值;

  • 多重索引选取数据,是通过切片进行的,切片是由小到大取的,例如字符串a→z,数字0→100。所以 多重索引选取数据时,要先对索引升序排序 ,才能正确地切片选取数据;

  • numpy np.min() 不识别空时间 NaT,当所有值均为NaT时,才返回NaT,只有有一个元素不为NaT,即返回非空元素中的最小值;

  • 由于numpy的空值与空值不相等,即 np.nan == np.nan 的结果为False,对空值的判断不能直接使用数学符号==或!=进行比较,而需要使用numpy自带的 np.isnan() 方法进行判断;

  • 判断dataframe列中的元素是否为空时,推荐使用了apply + lambda + np.isnan()的方式;

  • pd.concat进行2个dataframe按列合并时,必须满足2个dataframe的索引index都是从0开始的连续数列,否则会错位合并;

  • 在pandas中,没有 isnotin() ,可以通过取反的方式实现,取反的方法就是在函数前面加个~。例如:~(df.A == 4) ,等效于 df.A != 4;

  • 按指定的字符合并多列:df['A'].str.cat([df['B'], df['C']], sep='-');

  • 条件筛选数据时,优先推荐使用 query() 函数,因为写法更简洁,免去了写数据框名称的步骤,节省时间。特别地,要实现isin()的筛选需求,使用特定语法:df.query("col_name == @ designated_list");

  • 筛选数据内容的情况复杂时,推荐使用 contain() 函数,同时使用正则表达式辅助进行;

  • infer_objects() 函数,用于将具有对象数据类型的DataFrame的列,转换为更具体的类型,比如会把数值型或浮点型字符串列,转化成数值型或浮点型;

  • 获取某列的最大值或最小值对应的行索引,可以使用 idxmax()、idxmin() 函数,如:df["col_name"].idxmax();

  • 按列名或索引名对dataframe进行筛选时,通常使用 reindex() 函数即可满足80%的需求,当筛选条件复杂时,推荐使用 filter() 函数,可以指定名称列表、名称模糊匹配like、名称正则匹配,同时也可以指定方向axis;

  • cumsum() 函数:累加求和

  • cut() 函数:对列的值,进行离散化,即将连续变量,切割成区间段

  • 默认分成等距离区间,通过 bins 参数可以自定义区间列表
  • 通过 labels 参数可以为每个区间起名字
  • 特别地, labels=False 时,不是区间段,而是分类的序号
  • 结果区间列是分类变量 (Categories) ,操作时需留意,是否要转化为object
  • 该函数通常配合 groupby() 函数使用,进行区间分组
  • 默认区间段的范围是左开右闭, right 参数可以设置区间的开闭
  • 通过设置 include_lowest = False ,可以使第一个区间包含左端点
  • qcut() 函数:对列的值,按出现的次数进行切分,通过参数 q 设置分位数、或分类的个数,其它参数与cut()函数类似

  • 取某列数据中,前N大/小数据时,不需要先排序,再取前N个值,推荐使用 nlargest(n) nsmallest(n)

  • 获取dataframe中,每种数据类型的列数,使用 get_dtype_counts()

  • dropna() 函数删除空值时,参数 thresh 可以设定行至少包含的空值个数;参数 subset 可以设定仅对某几列中的空值进行删除;

  • fillna() 函数,进行空值替换时,参数 method 可以指定用前一个非缺失值去填充该缺失值(pad/ffill)、也可以指定用下一个非缺失值填充该缺失值(backfill/bfill);参数limit可以限制填充的个数;

  • combine_first() 函数,作用于Series数据结果,实现:用一个对象中的值填充另一个对象中对应位置的缺失值

  • get() 函数,作用于dataframe,使用2次get()函数可以获取指定位置的元素,第1次需要指定列名,第2次需要指定索引号,如:df.get("A").get(0)

  • groupby() 函数,不常用的功能

  • 默认会对组键进行排序,当数据量较大时,会影响性能和速度,通过设置sort=False可以不排序;
  • 当对多个字段进行分组时,会自动生成多级索引,若不需要输出多级索引,通过设置as_index=False可以避免多级索引;
  • size()函数计数时包含NaN值,而count()不包含NaN值,最常用的场景就是计算列的缺失率;
  • 统计不同值计数时,使用nunique()函数来实现;
  • 当需要对df的index和column同时分组时,列表中用df.index表示索引、列名称表示列;
  • Python函数在定义分组映射关系时,更有创意且更为抽象,任何被当做分组键的函数,都会在各个索引值上被调用一次,其返回值被用作分组名称。如示例中,对索引的字符串长度和A列,一起分组
  • df = pd.DataFrame({
        "A": ["yes", "no", "no", "yes", "yes"],
        "B": [0, 1, 2, 0, 2],
        "C": [10, 29, 100, 22, 11]},
        index = ["shi", "tou", "shimei", "mei", "doudou"])
             A  B   C
    shi     yes 0   10
    tou     no  1   29
    shimei  no  2   100
    mei   yes   0   22
    doudou  yes 2   11
    # 对索引的字符串长度和A列,一起分组
    df.groupby([len, "A"]).sum()
            B   C
    3   no  1   29
        yes 0   32
    6   no  2   100
        yes 2   11
    
  • 特别说明:groupby时,会自动过滤掉分组字段中为空的数据
  • merge()函数,当左右对象中存在除连接键外的同名列时,通过设置参数suffixes,对名称各加一个小尾巴(后缀),以便在结果中区分显示,该参数默认为 suffixes=('_x','_y')

  • 通过add_prefix()函数和add_suffix()函数,可以批量地为dataframe的所有列名,添加前缀或后缀;

  • map()函数是Series数据类型特有的方法,作用于每个元素;

  • apply()函数支持Series、DataFrame,前者作用于每个元素,后者作用于整个行或者列;

  • applymap()函数,支持Dataframe数据,作用于每个元素;

  • asof(where, subset=None)函数,返回指定索引行(where)及前面的数据中,最后一个不是NaN的值(Series)、或没有NaN的最后一行(DataFrame)。通常,where是索引为日期或日期数组的数据类型,也可以是索引号;

  • 设置pd.options.mode.chained_assignment = None会关闭掉copywarning,有人提到关闭这个warning后,速度更快,有待验证;

  • format()函数,与lambda函数配合,可以设置:四舍五入保留小数位、转化为百分数、添加千位分隔符等
    保留1位小数:df["A"].map(lambda x: format(x, '.1f'))
    设置百分数,并保留2位小数:df["A"].map(lambda x: format(x, '.2%'))
    设置千位分隔,并保留3位小数:df["A"].map(lambda x: format(x, ',.3f'))

  • pandas.Series._accessors,是一个功能非常强大的方法,可以理解为一种属性接口,通过它可以获得额外的方法,包括如下3个对象,通过这3个对象,可以获得Python中绝大多数的操作方法,而且操作的是一整列的数据。
    .cat:用于分类数据(Categorical data)
    .str:用于字符数据(String Object data)
    .dt:用于时间数据(datetime-like data)

  • read_clipboard()函数,直接从电脑的剪切板缓存区中提取数据,生成dataframe或Series。通常用法,在txt或excel中,选中并复制需要读取的内容,在IDE编辑器里,通过pd.read_clipboard()即可获取数据,其参数parse_dates参数设置为 "d",可以自动识别日期,并调整为xxxx-xx-xx的格式。

  • to_json()函数,将objects对象,打包成为 gzip, bz2, zip, or xz 等压缩格式,而不必将没压缩的文件放在内存中然后进行转化。

  • iat()函数,倒叙的方式取元素。该方法不管应用于序列还是数据框都非常优秀,主要体现在简介而高速,具体用法同python切片。

  • 数值列显示千分位(设置千分位后是字符串)

  • df['A'] = df['A'].apply(lambda x: format(x, ','))
    
  • 千分位数据转数值
  • df['A'] = df['A'].apply(lambda x: float(''.join(x.split(','))))