【问题标题】:Delete Column Rows with Any Numeric Substrings删除具有任何数字子字符串的列行
【发布时间】:2018-09-06 01:44:22
【问题描述】:

我注意到,当 Pandas DataFrame 中的列元素具有数字子字符串时,isnumeric 方法返回 false。

例如:

row 1, column 1 has the following: 0002 0003 1289
row 2, column 1 has the following: 89060 324 123431132
row 3, column 1 has the following: 890GB 32A 34311TT
row 4, column 1 has the following: 82A 34311TT
row 4, column 1 has the following: 82A 34311TT 889 9999C

很明显,第 1 行和第 2 行都是数字,但 isnumeric 对第 1 行和第 2 行返回 false。

我找到了一种解决方法,包括将每个子字符串分成它们自己的列,然后为每个子字符串创建一个布尔列,以将布尔值加在一起以显示一行是否全为数字。但是,这很乏味,而且我的功能看起来也不整洁。我也不想删除和替换空格(将所有子字符串压缩成一个数字),因为我需要保留原始子字符串。

有没有人知道一种更简单的解决方案/技术可以正确地告诉我这些带有一个或多个数字子字符串的元素都是数字的?我的最终目标是删除这些只有数字的行。

【问题讨论】:

    标签: python python-2.7 pandas delete-row isnumeric


    【解决方案1】:

    我认为需要splitall 的列表理解来检查所有数字字符串:

    mask = ~df['a'].apply(lambda x: all([s.isnumeric() for s in x.split()]))
    

    mask = [not all([s.isnumeric() for s in x.split()]) for x in df['a']]
    

    如果要检查是否至少有一个数字字符串使用any:

    mask = ~df['a'].apply(lambda x: any([s.isnumeric() for s in x.split()]))
    

    mask = [not any([s.isnumeric() for s in x.split()]) for x in df['a']]
    

    【讨论】:

    • 谢谢,我正在避免删除任何空格。我不太确定你在第一个那里做什么。 s.isnumeric 中的 s 来自哪里?因为我得到 '''str' 没有属性 'isnumeric'。
    • 我的代码:mask = ~df['ORGNTR_ACCT_ID'].apply(lambda x: all([str.isnumeric() for s in x.split()]))... 那就是包含子字符串行的列。
    • @spacedustpi - 您使用的是拆分字符串,所以需要s.isnumeric() 而不是str.isnumeric()
    • @spacedustpi 解释 - 对于每个值,首先将其拆分为空格,然后为每个拆分值检查是否为数字。它返回布尔值列表,所以需要all 来检查是否所有vslues 都是True
    • 感谢 jezrael,这适用于我的 python 3.6 环境!实际上,我两天前刚刚在 datacamp.com 上开始了关于屏蔽的教程,但还没有完成。 :)
    【解决方案2】:

    这是将pd.Series.mapany 与生成器表达式、str.isdecimalstr.split 一起使用的一种方法。

    import pandas as pd
    
    df = pd.DataFrame({'col1': ['0002 0003 1289', '89060 324 123431132', '890GB 32A 34311TT',
                                '82A 34311TT', '82A 34311TT 889 9999C']})
    
    df['numeric'] = df['col1'].map(lambda x: any(i.isdecimal() for i in x.split()))
    

    请注意,isdecimalmore strict 而不是 isdigit。但您可能需要在 Python 2.7 中使用 str.isdigitstr.isnumeric

    删除结果为False的这些行:

    df = df[df['col1'].map(lambda x: any(i.isdecimal() for i in x.split()))]
    

    结果

    逻辑的第一部分:

                        col1 numeric
    0         0002 0003 1289    True
    1    89060 324 123431132    True
    2      890GB 32A 34311TT   False
    3            82A 34311TT   False
    4  82A 34311TT 889 9999C    True
    

    【讨论】:

    • 谢谢,你用的是哪个版本的python?我收到错误消息:AttributeError: 'str' object has no attribute 'isdecimal'。
    • @spacedustpi,说得好。我有 3.6,所以你可能必须使用 str.isnumericstr.isdigit
    • 所以这段代码在我的 conda python 3.6 环境中运行,但是,为什么 index=4 出现了?显然它不是数字。只有子字符串 '889' 是数字。
    • 所以你需要用all替换any来实现这个逻辑。
    • 你打败了我。这就是我刚才所做的(duh),它奏效了,谢谢!
    猜你喜欢
    • 2019-03-27
    • 2019-02-08
    • 1970-01-01
    • 2016-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-08
    • 2017-02-12
    相关资源
    最近更新 更多