Pandas: замените строку на «other», если она отсутствует в списке строк

В целом это должно быть хорошо, но это возможно, если это не работает, если есть промежуточный кэш (прокси), который настроен на игнорирование параметров запроса.

Например, если вы обслуживая статический контент через CDN Akamai, он может быть настроен на игнорирование параметров запроса для предотвращения перебора кэша с использованием этого метода.

2
задан ronn 13 July 2018 в 10:29
поделиться

4 ответа

Мне кажется, нужно:

df['Class'] = np.where(df['Class'].isin(['Individual','Group']), df['Class'], 'Other')
print (df)
        Class
0  Individual
1       Group
2       Other
3       Other
4       Other
5       Other
6       Group

Другое решение (медленнее):

m = (df['Class'] == 'Individual') | (df['Class'] == 'Group')
df['Class'] = np.where(m, df['Class'], 'Other')

Другое решение:

df['Class'] = df['Class'].map({'Individual':'Individual', 'Group':'Group'}).fillna('Other')

Производительность (в реальных данных зависит от количества замен):

#[700000 rows x 1 columns]
df = pd.concat([df] * 100000, ignore_index=True)
#print (df)

In [208]: %timeit df['Class1'] = np.where(df['Class'].isin(['Individual','Group']), df['Class'], 'Other')
25.9 ms ± 485 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [209]: %timeit df['Class2'] = np.where((df['Class'] == 'Individual') | (df['Class'] == 'Group'), df['Class'], 'Other')
120 ms ± 6.63 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [210]: %timeit df['Class3'] = df['Class'].map({'Individual':'Individual', 'Group':'Group'}).fillna('Other')
95.7 ms ± 3.85 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [211]: %timeit df.loc[~df['Class'].isin(['Individual', 'Group']), 'Class'] = 'Other'
97.8 ms ± 6.78 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
6
ответ дан jezrael 17 August 2018 в 13:08
поделиться
  • 1
    Спасибо @jezrael. Решение помогло мне! – praveen 13 July 2018 в 10:37
  • 2
    Вау! Это отлично :) На данный момент я пошел с третьим решением. Но будет использовать первое решение в будущем. – praveen 13 July 2018 в 10:40

Вы можете сделать это таким образом, например

  1. получить список уникальных элементов list = df['Class'].unique()
  2. удалить свой известный класс list.remove('Individual') ....
  3. затем перечислить все другие строки df[df.class is in list]
  4. заменить значения класса df[df.class is in list].class = 'Other'

Извините за этот псевдо-псевдокод, но принцип тот же.

1
ответ дан Ashwel 17 August 2018 в 13:08
поделиться

Вы можете использовать pd.Series.where :

df['Class'].where(df['Class'].isin(['Individual', 'Group']), 'Other', inplace=True)

print(df)

        Class
0  Individual
1       Group
2       Other
3       Other
4       Other
5       Other
6       Group

Это должно быть эффективно против map + fillna:

df = pd.concat([df] * 100000, ignore_index=True)

%timeit df['Class'].where(df['Class'].isin(['Individual', 'Group']), 'Other')
# 60.3 ms per loop

%timeit df['Class'].map({'Individual':'Individual', 'Group':'Group'}).fillna('Other')
# 133 ms per loop
1
ответ дан jpp 17 August 2018 в 13:08
поделиться

Другой подход может быть:

df.loc[~df['Class'].isin(['Individual', 'Group']), 'Class'] = 'Other'
2
ответ дан zipa 17 August 2018 в 13:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: