Панды проверяют, какая подстрока находится в столбце строк - PullRequest
0 голосов
/ 18 апреля 2019

Я пытаюсь создать функцию, которая создаст новый столбец в фрейме данных 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

Ответы [ 5 ]

3 голосов
/ 18 апреля 2019

Делает ли это то, что вам нужно?

finds = ["m500_0", "0_500", "m150_0"]
df["t"] = df["x"].str.extract(f"({'|'.join(finds)})")
1 голос
/ 18 апреля 2019

Использование pandas.str.findall :

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

0    [m500_0]
1    [m500_0]
2     [0_500]
3    [m150_0]
1 голос
/ 18 апреля 2019

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

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
1 голос
/ 18 апреля 2019

Наверное, не лучший способ:

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) + ")")
0 голосов
/ 18 апреля 2019

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

df["t"] = df["x"].apply(lambda x: [i for i in finds if i in x][0])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...