Pandas Apply Function Ver Slow - Использование счетчиков значений при поиске по списку - PullRequest
0 голосов
/ 18 июня 2019

У меня есть DF pandas, который выглядит как ниже, и я пытаюсь транспонировать количество значений в разных строках в следующий формат:

   COL1    COL2    COL3
    C1      None    None
    C1      C2      None
    C1      C1      None
    C1      C2      C3

до

    C1  C2  C3
     1   0   0
     1   1   0
     2   0   0
     1   1   1

Я нашел этот ответ здесь ( Количество вхождений элементов в Серии в каждой строке DataFrame )

Это делает то, что мне нужно, но это очень медленно для моего набора данных (4 миллиона строк). Я попытался сделать это с 400 000 строк, и он все еще не работает с приемлемой скоростью.

Я полагаю, что этот список выполняет поиск по массиву данных, а применение apply по сути является циклом for. Это массивные петли, которые замедляют процесс. Потенциальные решения здесь по существу упоминают не использовать Apply, что сделало бы выполнение здесь утомительным, учитывая, что у меня есть C1, C2 ... C100 в моем списке и 10 вертикальных столбцов, чтобы проверить счет. Любые советы о том, что я мог бы попробовать здесь, чтобы улучшить производительность?

Вот код ниже:

df_store = df.apply(pd.Series.value_counts, axis=1)[list_lookup].fillna(0)

Ответы [ 2 ]

0 голосов
/ 18 июня 2019

Если вам нужно более быстрое решение, вам нужно использовать numpy.Используя горячее кодирование из numpy и присвойте результат ndarray в dataframe.Основываясь на моем %timeit, это примерно в 6 раз быстрее, чем Counter решение.Недостатком является то, что вам нужно заранее знать значения для кодирования, которые в вашем случае C1, C2, C3 .... C100

encode_val = np.array(['C1', 'C2', 'C3'])
encode_arr = (df.values[...,None] == encode_val).astype(int).sum(1)

Out[237]:
array([[1, 0, 0],
       [1, 1, 0],
       [2, 0, 0],
       [1, 1, 1]])

pd.DataFrame(encode_arr, columns=encode_val)

Out[238]:
   C1  C2  C3
0   1   0   0
1   1   1   0
2   2   0   0
3   1   1   1
0 голосов
/ 18 июня 2019

Именно поэтому мы обычно не используем apply

df.stack().str.get_dummies().sum(level=0).drop('None',1)
Out[157]: 
   C1  C2  C3
0   1   0   0
1   1   1   0
2   2   0   0
3   1   1   1

или делаем с Counter

from  collections import Counter


pd.DataFrame([ Counter(x) for x in df.values]).drop('None',1)
Out[170]: 
   C1   C2   C3
0   1  NaN  NaN
1   1  1.0  NaN
2   2  NaN  NaN
3   1  1.0  1.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...