DataFrame Группирует два столбца и получает счетчики другого - PullRequest
0 голосов
/ 13 октября 2019

Начинающий программист здесь ищет помощи. У меня есть Dataframe, который выглядит следующим образом:

  Cashtag      Date           Message  
0  $AAPL    2018-01-01   "Blah blah $AAPL"
1  $AAPL    2018-01-05   "Blah blah $AAPL"      
2  $AAPL    2019-01-08   "Blah blah $AAPL"     
3  $AAPL    2019-02-09   "Blah blah $AAPL"
4  $AAPL    2019-02-10   "Blah blah $AAPL"
5  $AAPL    2019-03-01   "Blah blah $AAPL"
6  $FB      2018-01-03   "Blah blah $FB"
7  $FB      2018-02-10   "Blah blah $FB"    
8  $FB      2018-02-11   "Blah blah $FB"   
9  $FB      2019-03-22   "Blah blah $FB" 
10 $AMZN    2018-04-13   "Blah blah $AMZN"
11 $AMZN    2018-04-29   "Blah blah $AMZN"
12 $AMZN    2019-07-23   "Blah blah $AMZN"     
13 $AMZN    2019-07-27   "Blah blah $AMZN"                         

Мой желаемый вывод - это DataFrame, который сообщает мне количество сообщений за каждый месяц каждого года в выборке для каждой компании. В этом примере это будет:

   Cashtag    Date    #Messages       
0  $AAPL    2018-01      02       
1  $AAPL    2019-01      01   
2  $AAPL    2019-02      02     
3  $AAPL    2019-03      01
4  $FB      2018-01      01
5  $FB      2018-02      02        
6  $FB      2019-03      01   
7  $AMZN    2018-04      02  
8  $AMZN    2019-07      02       

Я пробовал много комбинаций .groupby (), но не нашел решения.

Как мне достичь желаемого результата?

Ответы [ 3 ]

0 голосов
/ 13 октября 2019

Есть две хитрые части. Один из них обрабатывает даты, а другой - сам groupby .

Чтобы сгруппировать по годам и месяцам, вам нужно извлечь их из ваших дат. Вы можете использовать индексирование строк или преобразовать столбец «Дата» в datetimes и отформатировать их с помощью strftime. Я буду использовать второй метод, потому что нахожу его более читабельным, а также более полезным для изучения.

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

# convert Date to datetimes
df['Date'] = pd.to_datetime(df['Date'])
# extract year and month from datetime objects with `strftime`
df['year-month'] = df['Date'].apply(lambda x: (x.strftime('%Y-%m')))
# groupby columns 'Cashtag' and 'year-month' and aggregate 'Message' using the `count` function
df.groupby(['Cashtag', 'year-month'])['Message'].count()

Если вы не хотите создавать новый столбец, вы можете сделать это в одной строке:

df.groupby(['Cashtag', df['Date'].apply(lambda x: (x.strftime('%Y-%m')))])['Message'].count()
0 голосов
/ 13 октября 2019

Решение с использованием resample:

import pandas as pd


data = [
    ('$AAPL', '2018-01-01', "Blah blah $AAPL"),
    ('$AAPL', '2018-01-05', "Blah blah $AAPL"),      
    ('$AAPL', '2019-01-08', "Blah blah $AAPL"),     
    ('$AAPL', '2019-02-09', "Blah blah $AAPL"),
    ('$AAPL', '2019-02-10', "Blah blah $AAPL"),
    ('$AAPL', '2019-03-01', "Blah blah $AAPL"),
    ('$FB',   '2018-01-03', "Blah blah $FB"),
    ('$FB',   '2018-02-10', "Blah blah $FB"),  
]

df = pd.DataFrame.from_records(data=data, columns=['Cashtag', 'Date', 'Message'])


df['Date'] = pd.to_datetime(df['Date'])

df = (df
    .set_index(pd.DatetimeIndex(df['Date']))
    .groupby('Cashtag')
    .resample('M')['Message']
    .count()
    .reset_index()
    .query('Message > 0')
    .reset_index(drop=True)
)
df['Date'] = df['Date'].dt.to_period('M')

Вывод:

  Cashtag     Date  Message
0   $AAPL  2018-01        2
1   $AAPL  2019-01        1
2   $AAPL  2019-02        2
3   $AAPL  2019-03        1
4     $FB  2018-01        1
5     $FB  2018-02        1

Или даже более простое решение:

df['Date'] = pd.to_datetime(df['Date']).dt.to_period('M')
df = df.groupby(['Cashtag', 'Date'])['Message'].count().reset_index()
0 голосов
/ 13 октября 2019

Попробуйте:

В случае Date равно string:

>>> df.groupby([df["Cashtag"], df["Date"].apply(lambda x: x[:7])]).agg({"Message": "count"}).reset_index()

Если Date равно datetime:

>>> df.groupby([df["Cashtag"], df["Date"].apply(lambda x: "{0}-{1:02}".format(x.year, x.month))]).agg({"Message": "count"}).reset_index()

и выход:

  Cashtag     Date  Message
0   $AAPL  2018-01        2
1   $AAPL  2019-01        1
2   $AAPL  2019-02        2
3   $AAPL  2019-03        1
4   $AMZN  2018-04        2
5   $AMZN  2019-07        2
6     $FB  2018-01        1
7     $FB  2018-02        2
8     $FB  2019-03        1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...