#python #pandas #vectorization
#python #панды #векторизация
Вопрос:
У меня есть данные, которые выглядят как:
index stringColumn
0 A_B_B_B_C_C_D
1 A_B_C_D
2 B_C_D_E_F
3 A_E_F_F_F
Мне нужно векторизовать этот stringColumn с помощью счетчиков, в итоге:
index A B C D E F
0 1 3 2 1 0 0
1 1 1 1 1 0 0
2 0 1 1 1 1 1
3 1 0 0 0 1 3
Поэтому мне нужно сделать оба: подсчет и разделение. Функция Pandas str.get_dummies() позволяет мне разделить строку, используя аргумент sep = ‘_’, однако она не учитывает несколько значений. pd.get_dummies() выполняет подсчет, но не допускает разделения.
Мои данные огромны, поэтому я ищу векторизованные решения, а не циклы.
Ответ №1:
Вы можете использовать Series.str.split
с get_dummies
и sum
:
df1 = (pd.get_dummies(df['stringColumn'].str.split('_', expand=True),
prefix='', prefix_sep='')
.sum(level=0, axis=1))
Или подсчитайте значения по строкам на value_counts
, замените пропущенные значения на DataFrame.fillna
и преобразуйте в целые числа:
df1 = (df['stringColumn'].str.split('_', expand=True)
.apply(pd.value_counts, axis=1)
.fillna(0)
.astype(int))
Или используйте collections.Counter
, производительность должна быть очень хорошей:
from collections import Counter
df1 = (pd.DataFrame([Counter(x.split('_')) for x in df['stringColumn']])
.fillna(0)
.astype(int))
Или изменить форму по DataFrame.stack
и подсчитать по SeriesGroupBy.value_counts
:
df1 = (df['stringColumn'].str.split('_', expand=True)
.stack()
.groupby(level=0)
.value_counts()
.unstack(fill_value=0))
print (df1)
A B C D E F
0 1 3 2 1 0 0
1 1 1 1 1 0 0
2 0 1 1 1 1 1
3 1 0 0 0 1 3
Комментарии:
1. Все работает! Спасибо. Я хочу сообщить вам об их времени выполнения для небольшой части моего набора данных, чтобы их сложность была известна: 1-е решение: 15,3 секунды 2-е решение: 1,66 секунды 3-е решение: 44 миллисекунды! 4-е решение: 1.28 сек.