【问题标题】:Python pandas tagging entries in dataframe shortening codePython pandas 在数据帧缩短代码中标记条目
【发布时间】:2014-05-07 20:20:08
【问题描述】:

所以我使用 python pandas 有以下变量:

  • 一个数据框df,我创建了一个“TAG”列,用于将数据标记到 基于“IDnumber”列中的数据进行分组。
  • 存储在数组中的正则表达式模式pattern1pattern2pattern2-2, ...等
  • 一个数组group,其中填充了字符串(即:'software'、'engineering'、'marketing'...等)。

代码根据正则表达式模式pattern1pattern2pattern22、...等,用数组group中的字符串填充列df.TAG

到目前为止,我有工作代码,但有多个看起来相同的 for 循环存在冗余

for i in range(len(pattern1)):
    df.loc[df.IDnumber.str.contains(pattern1[i]) & (df.TAG == ''),'TAG'] = group[1]

for i in range(len(pattern2)):
    df.loc[df.IDnumber.str.contains(pattern2[i]) & (df.TAG == ''),'TAG'] = group[2]

for i in range(len(pattern22)):
    df.loc[df.IDnumber.str.contains(pattern22[i]) & (df.TAG == ''),'TAG'] = group[2]

for i in range(len(pattern33)):
    df.loc[df.IDnumber.str.contains(pattern33[i]) & (df.TAG == ''),'TAG'] = group[3]

for i in range(len(pattern3)):
    df.loc[df.IDnumber.str.contains(pattern3[i]) & (df.TAG == ''),'TAG'] = group[3]

我也收到了警告。

SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame
  df.loc[df.IDnumber.str.contains(pattern1[i]),'TAG'] = group[1]

但是代码可以工作,所以我想知道是否有一种方法可以通过减少 for 循环的数量来提高代码效率,并在不使用 pd.options.mode.chained_assignment = None 抑制警告的情况下删除警告。

【问题讨论】:

    标签: python regex pandas iteration


    【解决方案1】:

    你的第一个 for 循环:

    for i in range(len(pattern1)):
        df.loc[df.IDnumber.str.contains(pattern1[i]) & (df.TAG == ''),'TAG'] = group[1]
    

    可以替换为

    empty = (df.TAG == '')
    mask = df.IDnumber.str.contains('|'.join(pattern1)) & empty
    df.loc[mask, 'TAG'] = group[1]
    

    这可能会更快,因为整个循环被替换为一个正则表达式模式。可以为您的第二个也是最后一个 for-loops 进行类似的重构。

    但是你的第三个和第四个for-loops 让我感到困惑:for i in range(len(pattern2-2)):。 Python 名称不能包含连字符。那么pattern2-2 是什么意思呢?如果pattern2-2 只是另一个字符串数组(尽管变量名无效!?),那么您的第三个和第四个循环可以如上所示处理。


    如果所有的模式都是简单的字符串数组,那么你可以用类似的东西重构所有的 for 循环

    import itertools as IT
    patterns = [pattern1, pattern2, pattern3, pattern4, pattern5]
    empty = (df.TAG == '')
    for pattern, grp in IT.izip(patterns, group):
        mask = df.IDnumber.str.contains('|'.join(pattern)) & empty
        df.loc[mask, 'TAG'] = grp
    

    请注意,只要您有编号的变量名称,例如 pattern1pattern2 等@ 以上。然后,您只需使用patterns[0],而不是引用pattern1

    【讨论】:

    • 哎呀,破折号被意外添加了
    • 不确定,但看起来您的代码会将所有内容标记为 group[1]
    • for pattern, grp in IT.izip(patterns, group) 将使grp 逐步遍历group 中的值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-03
    • 1970-01-01
    • 2016-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多