Как применить строковые методы к нескольким столбцам данных - PullRequest
0 голосов
/ 30 августа 2018

У меня есть датафрейм с несколькими строковыми столбцами. Я хочу использовать строковый метод, который действителен для ряда в нескольких столбцах кадра данных. Примерно так я бы хотел:

df = pd.DataFrame({'A': ['123f', '456f'], 'B': ['789f', '901f']})
df

Out[15]: 
      A     B
0  123f  789f
1  456f  901f

df = df.str.rstrip('f')
df
Out[16]: 
     A    B
0  123  789
1  456  901

Очевидно, что это не работает, потому что операции str действительны только для объектов серии pandas. Каков подходящий / самый метод pandas-y для этого?

Ответы [ 3 ]

0 голосов
/ 30 августа 2018

Вы можете имитировать поведение rstrip, используя replace с regex=True, что может применяться ко всему DataFrame:

df.replace(r'f$', '', regex=True)

     A    B
0  123  789
1  456  901

Поскольку rstrip принимает последовательность символов для удаления, вы можете легко расширить это:

df.replace(r'[abc]+$', '', regex=True)
0 голосов
/ 30 августа 2018

Вы можете использовать словарь и передать конструктору pd.DataFrame:

res = pd.DataFrame({col: [x.rstrip('f') for x in df[col]] for col in df})

В настоящее время методы Панд str неэффективны. Regex еще более неэффективен, но его легче расширять. Как всегда, вы должны проверить свои данные.

# Benchmarking on Python 3.6.0, Pandas 0.19.2

def jez1(df):
    return df.apply(lambda x: x.str.rstrip('f'))

def jez2(df):
    return df.applymap(lambda x: x.rstrip('f'))

def jpp(df):
    return pd.DataFrame({col: [x.rstrip('f') for x in df[col]] for col in df})

def user3483203(df):
    return df.replace(r'f$', '', regex=True)

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

%timeit jez1(df)         # 33.1 ms per loop
%timeit jez2(df)         # 29.9 ms per loop
%timeit jpp(df)          # 13.2 ms per loop
%timeit user3483203(df)  # 42.9 ms per loop
0 голосов
/ 30 августа 2018

Функция rstrip работа с Series, поэтому возможно использование apply:

df = df.apply(lambda x: x.str.rstrip('f'))

Или создайте Series по stack и, наконец, unstack:

df = df.stack().str.rstrip('f').unstack()

Или используйте applymap:

df = df.applymap(lambda x: x.rstrip('f'))

Последнее, если необходимо применить функцию к некоторым столбцам:

#add columns to lists
cols = ['A']
df[cols] = df[cols].apply(lambda x: x.str.rstrip('f'))
df[cols] = df[cols].stack().str.rstrip('f').unstack()
df[cols] = df[cols].stack().str.rstrip('f').unstack()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...