【问题标题】:get index of the matching record获取匹配记录的索引
【发布时间】:2020-01-24 03:37:53
【问题描述】:

我有一个函数可以将字符串拆分为单词,然后在数据框中找到该单词,如果找到它,则使用 for 循环搜索该行,我不想这样做,因为它会使它太慢数据集。我想使用 row[value],并且不想为每个匹配的单词循环整个 df。

我是 python 新手,我已经搜索了很多,但可以得到我想要的,我找到了 index.tolist() 但我不想列出,我只需要第一个匹配值的索引.

任何帮助或解决方法将不胜感激。

def cal_nega_mean(my_string):
  mean = 0.00
  mean_tot = 0
  mean_sum = 0.00
  for word in my_string.split():
    if word in df.values: #at this point if it founds then get index, so that i dont have to use  for loop in next line
      for index, row in df.iterrows(): #want to change 
        if word == row.word:   # this part
          if row['value'] < -0.40:
            mean_tot += 1
            mean += row['value']
            break
  if mean_tot == 0:
    return 0
  mean = mean_sum / mean_tot
  return round(mean,2)

示例字符串输入,超过300k字符串

my_string = "i have a problem with my python code" 
cal_nega_mean(my_string)
# and i am using this to get return for all records
df_tweets['intensity'] = df_tweets['tweets'].apply(lambda row: cal_nega_mean(row))

要搜索的数据框

df 

index   word      value  ...

  1     python    -0.56

  2     problem   -0.78

  3     alpha     -0.91

   . . .

 9000   last    -0.41

【问题讨论】:

  • 您能否发布一些具有预期输出的数据。我很确定有一种方法可以在不循环的情况下完成此操作。
  • 使用pandas 时,最好尝试使用矢量化函数来完成您想要的,因为它更快。如果您可以向我们展示输入和输出,它将更有帮助
  • @ScottBoston 添加了完整的代码和数据示例
  • 您阅读过 Pandas 文档吗?显式循环很少是正确的选择。
  • 这能回答你的问题吗? Select by partial string from a pandas DataFrame

标签: python pandas dataframe


【解决方案1】:

您可以尝试使用i = df[df.word == word].index[0] 来获取满足条件df.word == word 的第一行的索引。获得索引后,您可以使用df.loc 切出该行。

def cal_nega_mean(my_string):
    mean = 0.00
    mean_tot = 0
    mean_sum = 0.00
    for word in my_string.split():
        try:
            i = df[df.word == word].index[0]
        except:
            continue
        row = df.loc[i]
        if row['value'] < -0.40:
            mean_tot += 1
            mean += row['value']
            break
    if mean_tot == 0:
        return 0
    mean = mean_sum / mean_tot
    return round(mean,2)

【讨论】:

  • 这就是我要找的,要得到匹配记录的id,我明天试试,看看它是否有效
【解决方案2】:

Pandas 有一些有用的文本处理功能可以帮助您。我建议你使用pd.Series.str.contains()

def cal_nega_mean(my_string):
    words = '|'.join(my_string.split())
    matches = df['word'].str.contains(words, regex=True)
    mask = (df['value'] >= -0.40) & matches # don't need value >= -0.40 if you just drop those rows
    mean_tot = mask.sum()
    mean_sum = df[mask]['value'].sum()
    mean = mean_sum / mean_tot
    return round(mean, 2)

不相关,但我也建议您只删除“值”

我没有机会对此进行测试,但它应该可以完成这项工作,而且它是矢量化的。

【讨论】:

  • 好的,你的解决方案似乎更短更好,我明天试试,不,我没有丢弃或忽略值,它只是一个示例,条件是动态的,它取决于其他东西
  • 您的解决方案既好又快,但是当字符串包含括号“(”等时会出错
【解决方案3】:

这是一种使用字典的方法,您可以将word: value 转换为键、值存储并将其用作查找:

word_look_up = dict(zip(df['word'], df['value']))


def cal_nega_mean(my_string): 
    mean = 0.0
    mean_tot = 0
    mean_sum = 0.00
    words = [word for word in my_string.split() if word in word_look_up]

    if not any(words): # if no word found
        return 0
    else:
        for word in words:
            value = word_look_up[word]
            if value < -0.40:
                mean_tot += 1
                mean += value
                break

    mean = mean / mean_tot
    return round(mean, 2)


df['intensity'] = df['word'].apply(cal_nega_mean)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多