【问题标题】:Remove contents of an array from a column in pandas从 pandas 的列中删除数组的内容
【发布时间】:2018-03-15 13:18:23
【问题描述】:

我正在尝试删除数组的内容 positions = ['CF','ST','RW','LW','CB','RB','LB','CM','CAM','CDM','RM','LM','RWB','LWB'] 来自我的数据框中包含足球运动员的名称列。下面是此数据框的示例。 Player dataframe

谁能帮我删除这些字符串,我试过 str.replace 还是不行,

谢谢

【问题讨论】:

  • 在使用str.replace的时候有没有使用inplace参数
  • @MichaelMallon,我能问一下你用什么来做基准测试吗?我发现 jezrael 的解决方案比我的慢约 15 倍..
  • 但是不要相信我的话..请测试一下,看看什么对你有用!
  • @jpp 对不起,我没有看到你的答案都很好我已经给了你正确的答案,因为在我进行基准测试后你的答案更快

标签: python pandas dataframe jupyter-notebook


【解决方案1】:

下面的方法专门匹配空格分隔的值。

df = pd.DataFrame({'Player': ['ABC CF ST RW', 'DEF LB CM', 'GHI RM', 'JKL']})

rem = ['CF','ST','RW','LW','CB','RB','LB',
       'CM','CAM','CDM','RM','LM','RWB','LWB']

rem_set = set(rem)

def remover(p):
    return ' '.join([x for x in p.split() if x not in rem_set])

df['Player'] = df['Player'].map(remover)

#   Player
# 0    ABC
# 1    DEF
# 2    GHI
# 3    JKL

性能基准测试

df = pd.DataFrame({'Player': ['ABC CF ST RW', 'DEF LB CM', 'GHI RM', 'JKL']})

rem = ['CF','ST','RW','LW','CB','RB','LB',
       'CM','CAM','CDM','RM','LM','RWB','LWB']

rem_set = set(rem)

df = pd.concat([df]*20000)

def jez(df):
    d = {r'(\b){}(\b)'.format(x):r'' for x in rem_set}
    df['Player'] = df['Player'].replace(d, regex=True)
    return df

def jp(df):
    def remover(p):
        return ' '.join([x for x in p.split() if x not in rem_set])

    df['Player'] = df['Player'].map(remover)
    return df

%timeit jez(df)  # 1.24s
%timeit jp(df)   # 86ms

【讨论】:

    【解决方案2】:

    我认为如果有必要删除最后一个空格之后的所有字符串:

    df['Name'] = df['Name'].str.rsplit(n=1).str[0]
    

    或者如果需要仅删除 positions 的值(使用 jpp DataFrame):

    d = {r'\s+(\b){}(\b)'.format(x):r'' for x in positions}
    df['Name'] = df['Name'].replace(d, regex=True)
    print (df)
      Name
    0  ABC
    1  DEF
    2  GHI
    3  JKL
    

    【讨论】:

    • 我喜欢这个解决方案,因为它很干净,但它的性能似乎很差。可能又与df.series.replace 有关。
    【解决方案3】:

    您可能会发现只删除末尾所有 2 或 3 个字符的大写条目就足够了,如下所示:

    import pandas as pd
    
    data = [
        ['Name', 'Overall', 'Club'], 
        ['L. Messi CF ST RW', 94, 'FC Barcelona'],
        ['Cristiano Ronaldo LW LM ST RM', 92, 'Real Madrid CF']]
    
    df = pd.DataFrame(data[1:], columns=data[0])    
    df['Name'] = df['Name'].replace(r'((\s+[A-Z]{2,3}))+$', '', regex=True)
    
    print(df)
    

    这会给你:

                    Name  Overall            Club
    0           L. Messi       94    FC Barcelona
    1  Cristiano Ronaldo       92  Real Madrid CF
    

    【讨论】:

      【解决方案4】:
      df = pd.DataFrame({"Name": ["James kon CF ST RW", "Rom CAM"], "Overall": [23,65], "Club": ["a", "b"]})
      
      positions = set(['CF','ST','RW','LW','CB','RB','LB','CM','CAM','CDM','RM','LM','RWB','LWB'])
      
      def f(name, position):
          item = set(name.split(" "))
          newobj = item - position
          return " ".join(newobj)
      
      df["Name"].map(lambda x: f(x, positions))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-07-15
        • 1970-01-01
        • 1970-01-01
        • 2014-11-10
        • 2020-07-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多