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

统计每行中的字符数,如果所有字符数都低于某个数字,则删除

  •  1
  • DrakeMurdoch  · 技术社区  · 6 月前

    我有一个包含许多列的数据框,所有列都包含混合的文本数据 NaNs .

    我想计算每列中每个单元格的字符数,然后删除其中的任何行 全部的 列的长度少于5个字符(如果任何单元格的长度超过5个字符,则该行不会被删除)。

    我在考虑用 str.len 对于每一列,然后使用它过滤掉行,但这似乎很麻烦。

    例子:

    >>> df
       column_1    column_2    column_3
    0   werhi      dsfhjk       dh      ---> not filtered because some columns have more than 5 characters
    1   sgds        fuo         g       ---> filtered
    2   wqyuio      dsklh       fhkjfj
    3   fhi         d           fgho    ---> filtered
    4   sadfhkj     sdjfkhs     yyisdk
    
    >>> df_filtered
       column_1    column_2    column_3
    0   werhio      dsfhjk      dh
    2   wqyuio      dsfjklh     fhkjfj
    4   sadfhkj     sdjfkhs     yyisdk
    
    2 回复  |  直到 6 月前
        1
  •  1
  •   mozway    6 月前

    无需创建新列。

    选项1:每行最小字符串总长度

    只是 apply 对所有列进行合计 sum 并为创建一个布尔序列 boolean indexing :

    thresh = 10
    out = df[df.apply(lambda x: x.str.len()).sum(axis=1).ge(thresh)]
    

    输出:

      column_1 column_2 column_3
    0   werhio   dsfhjk       dh
    2   wqyuio  dsfjklh   fhkjfj
    4  sadfhkj  sdjfkhs   yyisdk
    

    选项2:行中任何字符串的最小字符串长度

    如果要确保列中的所有值至少具有给定的大小,请在聚合之前与阈值进行比较 any :

    thresh = 5
    df[df.apply(lambda x: x.str.len()).ge(thresh).any(axis=1)]
    

    输出:

    第一列第二列第三列
    0 werhio dsfhjk dh
    2 wqyuio dsfjklh fhkjfj
    4 sadfhkj sdjfkhs yyisdk
    

    中间体

    选项1:

    # df.apply(lambda x: x.str.len())
       column_1  column_2  column_3
    0         6         6         2
    1         4         3         1
    2         6         7         6
    3         3         1         4
    4         7         7         6
    
    # df.apply(lambda x: x.str.len()).sum(axis=1)
    0    14
    1     8
    2    19
    3     8
    4    20
    dtype: int64
    
    # df.apply(lambda x: x.str.len()).sum(axis=1).ge(thresh)
    0     True
    1    False
    2     True
    3    False
    4     True
    dtype: bool
    

    选项2:

    # df.apply(lambda x: x.str.len().ge(5))
       column_1  column_2  column_3
    0      True      True     False
    1     False     False     False
    2      True      True      True
    3     False     False     False
    4      True      True      True
    
    # df.apply(lambda x: x.str.len().ge(5)).any(axis=1)
    0     True
    1    False
    2     True
    3    False
    4     True
    dtype: bool
    
        2
  •  0
  •   Ali Raza    6 月前
    import pandas as pd
    import numpy as np
    
    data = {
        'col1': ['abc', 'de', 'fghi', 'jklmn'],
        'col2': ['opq', 'r', 'stuv', 'wx'],
        'col3': ['y', 'z', '123', '45678']
    }
    df = pd.DataFrame(data)
    
    threshold = 3
    
    # For sum of all columns in a row being greater than threshold:
    row_filter = df.apply(lambda col: col.str.len()).sum(axis=1) >= threshold
    
    # For each columns minimum value being greater than threshold:
    row_filter = df.apply(lambda col: col.str.len()).min(axis=1) >= threshold
    
    filtered_df = df[row_filter]
    
    1. applymap(len) 将创建一个新的DF,该DF具有原始DF中每个字符串的长度
    2. sum(axis=1) 将对行中所有字符串的长度求和
    3. >= threshold 将过滤掉小于所需长度的行
    4. filtered_df = df[row_filter] 将过滤原始数据帧,以排除与谓词不匹配的行