美文网首页
Pandas基础之常见的坑

Pandas基础之常见的坑

作者: 惑也 | 来源:发表于2019-06-24 00:47 被阅读0次

    坑点集

    • 当数据中含有缺失值、特殊字符时,若使用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()函数:对列的值,进行离散化,即将连续变量,切割成区间段

    1. 默认分成等距离区间,通过bins参数可以自定义区间列表
    2. 通过labels 参数可以为每个区间起名字
    3. 特别地,labels=False时,不是区间段,而是分类的序号
    4. 结果区间列是分类变量(Categories),操作时需留意,是否要转化为object
    5. 该函数通常配合groupby()函数使用,进行区间分组
    6. 默认区间段的范围是左开右闭,right参数可以设置区间的开闭
    7. 通过设置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()函数,不常用的功能

    1. 默认会对组键进行排序,当数据量较大时,会影响性能和速度,通过设置sort=False可以不排序;
    2. 当对多个字段进行分组时,会自动生成多级索引,若不需要输出多级索引,通过设置as_index=False可以避免多级索引;
    3. size()函数计数时包含NaN值,而count()不包含NaN值,最常用的场景就是计算列的缺失率;
    4. 统计不同值计数时,使用nunique()函数来实现;
    5. 当需要对df的index和column同时分组时,列表中用df.index表示索引、列名称表示列;
    6. 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"])
    
    df
             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
        A       
    3   no  1   29
        yes 0   32
    6   no  2   100
        yes 2   11
    
    1. 特别说明: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(','))))
    
    • 设置保留小数
    pd.set_option('display.float_format', lambda x: '{:,.4f}'.format(x))
    

    相关文章

      网友评论

          本文标题:Pandas基础之常见的坑

          本文链接:https://www.haomeiwen.com/subject/nngvoqtx.html