Pandas проверяет, какая подстрока находится в столбце строк

#python #pandas #dataframe

#python #pandas #фрейм данных

Вопрос:

Я пытаюсь создать функцию, которая создаст новый столбец в фрейме данных pandas, где он определяет, какая подстрока находится в столбце строк, берет подстроку и использует ее для нового столбца.

Проблема в том, что текст для поиска не отображается в том же месте в переменной x

  df = pd.DataFrame({'x': ["var_m500_0_somevartext","var_m500_0_vartextagain",
 "varwithsomeothertext_0_500", "varwithsomext_m150_0_text"], 'x1': [4, 5, 6,8]})

finds = ["m500_0","0_500","m150_0"]
 

какая из finds них находится в данной df["x"] строке

Я создал функцию, которая работает, но ужасно медленно для больших наборов данных

 def pd_create_substring_var(df,new_var_name = "new_var",substring_list=["1"],var_ori="x"):
    import re
    df[new_var_name] = "na"
    cols =  list(df.columns)
    for ix in range(len(df)):
        for find in substring_list:
            for m in re.finditer(find, df.iloc[ix][var_ori]):
                df.iat[ix, cols.index(new_var_name)] = df.iloc[ix][var_ori][m.start():m.end()]
    return df


df = pd_create_substring_var(df,"t",finds,var_ori="x")

df 
                            x  x1       t
0      var_m500_0_somevartext   4  m500_0
1     var_m500_0_vartextagain   5  m500_0
2  varwithsomeothertext_0_500   6   0_500
3   varwithsomext_m150_0_text   8  m150_0
 

Ответ №1:

Выполняет ли это то, что вам нужно?

 finds = ["m500_0", "0_500", "m150_0"]
df["t"] = df["x"].str.extract(f"({'|'.join(finds)})")
 

Комментарии:

1. Хороший, я попробовал это, но немного отклонился и отказался от этой идеи

Ответ №2:

Используйте pandas.str.findall:

df['x'].str.findall("|".join(finds))

 0    [m500_0]
1    [m500_0]
2     [0_500]
3    [m150_0]
 

Ответ №3:

Вероятно, не лучший способ:

 df['t'] = df['x'].apply(lambda x: ''.join([i for i in finds if i in x]))
 

И теперь:

 print(df)
 

Является:

                             x  x1       t
0      var_m500_0_somevartext   4  m500_0
1     var_m500_0_vartextagain   5  m500_0
2  varwithsomeothertext_0_500   6   0_500
3   varwithsomext_m150_0_text   8  m150_0
 

И теперь, просто добавив к ответу @pythonjokeun, вы можете сделать:

 df["t"] = df["x"].str.extract("(%s)" % '|'.join(finds))
 

Или:

 df["t"] = df["x"].str.extract("({})".format('|'.join(finds)))
 

Или:

 df["t"] = df["x"].str.extract("("   '|'.join(finds)   ")")
 

Комментарии:

1. первое, что вы показываете, является самым быстрым для моего большого набора данных из 180000 строк и, в отличие от ответа @pythonjokeun, он может работать на python 3.5

Ответ №4:

Я не знаю, насколько велик ваш набор данных, но вы можете использовать функцию map, как показано ниже:

 def subset_df_test():
  df = pandas.DataFrame({'x': ["var_m500_0_somevartext", "var_m500_0_vartextagain",
                         "varwithsomeothertext_0_500", "varwithsomext_m150_0_text"], 'x1': [4, 5, 6, 8]})

  finds = ["m500_0", "0_500", "m150_0"]
  df['t'] = df['x'].map(lambda x: compare(x, finds))
  print df

def compare(x, finds):
  for f in finds:
    if f in x:
        return f
 

Ответ №5:

Попробуйте это

 df["t"] = df["x"].apply(lambda x: [i for i in finds if i in x][0])