Pandas groupby и значение рассчитывают для сложных строк, которые встречаются несколько раз - PullRequest
0 голосов
/ 30 апреля 2018

Предположим, у меня есть df, как это:

    stringOfInterest        trend                  
0         C                    up
1         D                  down
2         E                  down
3         C,O                  up
4         C,P                  up

Я хочу построить это df как гистограмму, используя pandas. Чтобы получить правильные сгруппированные гистограммы, я хотел бы сгруппировать данные по столбцу df["trend"], а затем посчитать вхождение df["stringOfInterest"] для каждой буквы . Как видно, некоторые из этих строк содержат несколько букв, разделенных ",".

Использование

df.groupby("trend").stringOfInterest.value_counts().unstack(0)

дает ожидаемый результат:

trend                  down    up
stringOfInterest                        
-                       7.0   8.0
C                       3.0  11.0
C,O                     NaN   2.0
C,P                     1.0   1.0
D                       1.0   2.0
E                      15.0  14.0
E,T                     1.0   NaN

Однако я хотел бы посчитать вхождение отдельных символов (C, E, D, ...). На оригинальном df это может быть достигнуто следующим образом:

s = df.stringOfInterest.str.split(",", expand = True).stack()
s.value_counts()

Обычно это генерирует что-то вроде этого:

C     3
E     2
D     1
O     1
P     1
T     1

К сожалению, здесь нельзя использовать после groupby() в сочетании с unstack().

Может быть, я не на том пути, и предпочтительнее будет какой-нибудь более элегантный способ.

Для пояснения графика: Для каждой буквы (stringOfInterest) должно быть два бара, указывающих количество тренда «вверх» и «вниз».

1 Ответ

0 голосов
/ 30 апреля 2018

На основании этого ответа здесь: Панды расширяют строки из списка данных, доступных в столбце

Это тебе чем-то поможет?

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame(
    {'stringOfInterest': {0: 'C', 1: 'D', 2: 'E', 3: 'C,O', 4: 'C,P'},
     'trend': {0: 'up', 1: 'down', 2: 'down', 3: 'up', 4: 'up'}})


df2 = (pd.DataFrame(df.stringOfInterest.str.split(',').tolist(), index=df.trend)
        .stack()
        .reset_index()
        .groupby('trend')[0]
        .value_counts()
        .unstack()
      ).T

df2.plot(kind='bar')
plt.show()

Другой подход

Мы также можем сжать столбцы вместе и развернуть.

import pandas as pd
from collections import Counter

data = [(x,i) for x,y in zip(df.trend,df.stringOfInterest.str.split(',')) for i in y]

pd.Series(Counter(data)).plot(kind='bar')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...