Как сгруппировать по дате с пандами?

1

Я сделал игру и получил данные игроков следующим образом:

StartTime                    Id    Rank Score
2018-04-24 08:46:35.684000    aaa    1    280
2018-04-24 23:54:47.742000    bbb    2    176
2018-04-25 15:28:36.050000    ccc    1    223
2018-04-25 00:13:00.120000    aaa    4    79
2018-04-26 04:59:36.464000    ddd    1    346
2018-04-26 06:01:17.728000    fff    2    157
2018-04-27 04:57:37.701000    ggg    4    78

но я хочу группировать его днем, просто так:

Date    2018/4/24    2018/4/25    2018/4/26    2018/4/27
ID        aaa            ccc          ddd            ggg
          bbb            aaa          fff            NaN

как мне группироваться по дате с помощью Pandas?

Теги:
pandas
dataframe
pandas-groupby

3 ответа

0
Лучший ответ

Вы можете использовать cumcount для выравнивания индекса по группам, а затем concat конкатенировать серии.

# normalize to zero out time
df['StartTime'] = pd.to_datetime(df['StartTime']).dt.normalize()

# get unique days and make index count by group
cols = df['StartTime'].unique()
df.index = df.groupby('StartTime').cumcount()

# concatenate list comprehension of series
res = pd.concat([df.loc[df['StartTime'] == i, 'Id'] for i in cols], axis=1)
res.columns = cols

print(res)

  2018-04-24 2018-04-25 2018-04-26 2018-04-27
0        aaa        ccc        ddd        ggg
1        bbb        aaa        fff        NaN

Спектакль

Для небольших фреймов данных используйте @ScottBoston более сжатое решение. Для больших dataframes, concat, кажется, лучше масштабируется, чем unstack:

def scott(df):
    df['StartTime'] = pd.to_datetime(df['StartTime'])
    return df.set_index([df['StartTime'].dt.floor('D'),
                  df.groupby(df['StartTime'].dt.floor('D')).cumcount()])['Id'].unstack(0)

def jpp(df):
    df['StartTime'] = pd.to_datetime(df['StartTime']).dt.normalize()
    df.index = df.groupby('StartTime').cumcount()
    res = pd.concat([df.loc[df['StartTime'] == i, 'Id'] for i in df['StartTime'].unique()], axis=1)
    res.columns = cols
    return res

df2 = pd.concat([df]*100000)

%timeit scott(df2)  # 1 loop, best of 3: 681 ms per loop
%timeit jpp(df2)    # 1 loop, best of 3: 271 ms per loop
  • 0
    Thx братан, все твои функции работали хорошо !! Теперь я сталкиваюсь с новой проблемой, я нашел много дубликатов данных за день, поэтому я использовал res.drop_duplicates(res.columns) чтобы удалить их, но это не работает, почему?
  • 0
    @AlexRan, Сложно сказать, вы можете попробовать быть явным res = res.drop_duplicates() .
Показать ещё 5 комментариев
0

Используйте set_index и cumcount:

df.set_index([df['StartTime'].dt.floor('D'),
              df.groupby(df['StartTime'].dt.floor('D')).cumcount()])['Id'].unstack(0)

Выход:

StartTime 2018-04-24 2018-04-25 2018-04-26 2018-04-27
0                aaa        ccc        ddd        ggg
1                bbb        aaa        fff        NaN
0
import pandas as pd

df = pd.DataFrame({'StartTime': ['2018-04-01 15:25:11', '2018-04-04 16:25:11', '2018-04-04 15:27:11'], 'Score': [10, 20, 30]})
print(df)

Это дает

   Score            StartTime
0     10  2018-04-01 15:25:11
1     20  2018-04-04 16:25:11
2     30  2018-04-04 15:27:11

Теперь мы создаем новый столбец на основе столбца StartTime, который содержит только дату:

df['Date'] = df['StartTime'].apply(lambda x: x.split(' ')[0])
print(df)

Выход:

   Score            StartTime        Date
0     10  2018-04-01 15:25:11  2018-04-01
1     20  2018-04-04 16:25:11  2018-04-04
2     30  2018-04-04 15:27:11  2018-04-04

Теперь мы можем использовать метод pd.DataFrame.groupby для группировки строк по значениям нового столбца Date. В приведенном ниже примере я сначала группирую столбцы, а затем перебираю их, чтобы напечатать имя (значение столбца " Date этой группы) и достигнутый средний результат:

for name, group in df.groupby('Date'):
    print(name)
    print(group)
    print(group['Score'].mean())

дает:

2018-04-01
   Score            StartTime        Date
0     10  2018-04-01 15:25:11  2018-04-01
10.0
2018-04-04
   Score            StartTime        Date
1     20  2018-04-04 16:25:11  2018-04-04
2     30  2018-04-04 15:27:11  2018-04-04
25.0

Изменить. Поскольку вы изначально не предоставляли данные данных данных в формате таблицы, я оставляю это как упражнение для вас, чтобы адаптировать данные в моем ответе ;-)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню