代码之家  ›  专栏  ›  技术社区  ›  SethMMorton

更改数据帧列类型的简单方法,但对错误使用默认值?

  •  3
  • SethMMorton  · 技术社区  · 9 年前

    假设我有以下专栏。

    >>> import pandas
    >>> a = pandas.Series(['0', '1', '5', '1', None, '3', 'Cat', '2'])
    

    int ,任何无法转换的元素都应替换为 0 .

    我目前的解决方案是使用 to_numeric 'coerce' 选项,填充任意 NaN 具有 ,然后转换为 (自 制作专栏 float 而不是 整数 ).

    >>> pandas.to_numeric(a, errors='coerce').fillna(0).astype(int)
    0    0
    1    1
    2    5
    3    1
    4    0
    5    3
    6    0
    7    2
    dtype: int64
    

    有什么方法可以让我在 而不是必须经历两个中间状态? 我正在寻找一种行为类似于以下想象的选项的东西 astype

    >>> a.astype(int, value_on_error=0)
    
    2 回复  |  直到 9 年前
        1
  •  4
  •   piRSquared    9 年前

    选项1

    pd.to_numeric(a, 'coerce').fillna(0).astype(int)
    

    b = pd.to_numeric(a, 'coerce')
    b.mask(b.isnull(), 0).astype(int)
    

    选项3

    def try_int(x):
        try:
            return int(x)
        except:
            return 0
    
    a.apply(try_int)
    

    选项4

    b = np.empty(a.shape, dtype=int)
    
    i = np.core.defchararray.isdigit(a.values.astype(str))
    
    b[i] = a[i].astype(int)
    b[~i] = 0
    
    pd.Series(b, a.index)
    

    所有产品

    0    0
    1    1
    2    5
    3    1
    4    0
    5    3
    6    0
    7    2
    dtype: int64
    


    代码如下

    enter image description here

    def pir1(a):
        return pd.to_numeric(a, 'coerce').fillna(0).astype(int)
    
    def pir2(a):
        b = pd.to_numeric(a, 'coerce')
        return b.mask(b.isnull(), 0).astype(int)
    
    def try_int(x):
        try:
            return int(x)
        except:
            return 0
    
    def pir3(a):
        return a.apply(try_int)
    
    def pir4(a):
        b = np.empty(a.shape, dtype=int)
    
        i = np.core.defchararray.isdigit(a.values.astype(str))
    
        b[i] = a[i].astype(int)
        b[~i] = 0
        return pd.Series(b, a.index)
    
    
    def alt1(a):
        return pd.to_numeric(a.where(a.str.isnumeric(), 0))
    
    results = pd.DataFrame(
        index=[1, 3, 10, 30, 100, 300, 1000, 3000, 10000],
        columns='pir1 pir2 pir3 pir4 alt1'.split()
    )
    
    for i in results.index:
        c = pd.concat([a] * i, ignore_index=True)
        for j in results.columns:
            stmt = '{}(c)'.format(j)
            setp = 'from __main__ import c, {}'.format(j)
            results.set_value(i, j, timeit(stmt, setp, number=10))
    
    results.plot(logx=True, logy=True)
    
        2
  •  1
  •   Scott Boston    9 年前
    a.where(a.str.isnumeric(),0).astype(int)
    

    输出:

    0    0
    1    1
    2    5
    3    1
    4    0
    5    3
    6    0
    7    2
    dtype: int64