如何按日期范围对熊猫数据框行进行分组

时间:2019-02-16 19:28:09

标签: python pandas

这是我处理熊猫和数据操作的第一步。 我从kaggle(https://www.kaggle.com/pablote/nba-enhanced-stats)获得了篮球比赛的统计数据。该数据集包含从2012年10月31日到2018年10月31日的日期时间列。

我想按日期范围(更准确的说是nba季节)对行进行分组,这意味着我需要: -第一组(2012年10月31日至2013年7月31日) -2013年10月31日至2014年7月31日第二组,依此类推,直到 -从2017年10月21日到2018年7月31日的第n组。

我读了一些有关groupby,日期范围的话题,但是我不确定这是否适合我的情况。

下面是我正在使用的代码(jupyter笔记本)

import pandas as pd
df1 = pd.read_csv('2012-18_teamBoxScore.csv')
df1.shape, df1.keys()
    ((14758, 123),
     Index(['gmDate', 'gmTime', 'seasTyp', 'offLNm1', 'offFNm1', 'offLNm2',
    'offFNm2', 'offLNm3', 'offFNm3', 'teamAbbr',
    ...
    'opptFIC40', 'opptOrtg', 'opptDrtg', 'opptEDiff', 'opptPlay%', 'opptAR',
    'opptAST/TO', 'opptSTL/TO', 'poss', 'pace'],
    dtype='object', length=123))
df1['gmDate'] = pd.to_datetime(df1['gmDate'])  # convert dmDate from string to datetime
# get data from a specific team
gs_df = df1[['gmDate', 'gmTime', 'teamAbbr', 'teamLoc', 'teamRslt', 'opptAbbr', 'opptLoc','opptRslt']][(df1.teamAbbr == 'GS')]
gs_df.shape
    (492, 8)
gs_df.groupby(pd.Grouper(key='gmDate', freq='BA-SEP')).groups
    {Timestamp('2013-09-30 00:00:00', freq='BA-SEP'): 82,
     Timestamp('2014-09-30 00:00:00', freq='BA-SEP'): 164,
     Timestamp('2015-09-30 00:00:00', freq='BA-SEP'): 246,
     Timestamp('2016-09-30 00:00:00', freq='BA-SEP'): 328,
     Timestamp('2017-09-29 00:00:00', freq='BA-SEP'): 410,
     Timestamp('2018-09-28 00:00:00', freq='BA-SEP'): 492}

在这里我们可以看到分组实际上是一个累积分组,而我希望每个分组有82行

进行此拆分的最佳方法是什么?

感谢您的反馈

S

2 个答案:

答案 0 :(得分:1)

您可以使用Pandas Groupby Range of Values所述的pandas cut方法。在使用剪切功能之前,您可能需要将日期转换为数字时间戳。

答案 1 :(得分:1)

我认为在这种情况下,我想在其中列出实际赛季,例如2017赛季,然后使用赛季,球队,比赛做一个多指标。使用这种方法,您可以根据需要对数据进行切片和切块。

import pandas as pd
import numpy as np

df1 = pd.read_csv('2012-18_teamBoxScore.csv')

# convert dmDate from string to datetime
df1['gmDate'] = pd.to_datetime(df1['gmDate'])  

# list of start dates, and the end date to the last year
dates = [
    "2012-09-30",
    "2013-09-30",
    "2014-09-30",
    "2015-09-30",
    "2016-09-30",
    "2017-09-29",
    "2018-09-28",
    "2019-09-28",
]

# make dates datetime
dates = pd.to_datetime(dates)

seasons = ['2012', '2013', '2014', '2015', '2016', '2017', '2018']

# create a season column using cut
df1['season'] = pd.cut(df1['gmDate'], dates, labels=seasons)

# a multiindex is easier to work with
df1.set_index(['teamAbbr', 'season', 'gmDate'], inplace=True)

columns = ['gmTime', 'teamLoc', 'teamRslt', 'opptAbbr', 'opptLoc','opptRslt']

# use an [index slicer][1] to get whatever data you want.
idx = pd.IndexSlice
df1.loc[idx[['CLE', 'DAL'], ['2012', '2014'], slice(None)],columns].head(2)

对于结果:

                              gmTime  teamLoc  teamRslt opptAbbr opptLoc opptRslt
teamAbbr    season  gmDate                      
CLE          2012   2012-10-30  19:00   Home    Win       WAS     Away    Loss
DAL          2012   2012-10-30  22:30   Away    Win       LAL     Home    Loss


# if you want to see all seasons or all teams, just replace with slice(None)
df1.loc[idx[['CLE'], slice(None), slice(None)],columns]

                      gmTime teamLoc teamRslt opptAbbr opptLoc opptRslt
teamAbbr season gmDate                      
CLE 2012    2012-10-30  19:00   Home    Win     WAS     Away    Loss
            2012-11-02  19:30   Home    Loss    CHI     Away    Win
            2012-11-03  20:30   Away    Loss    MIL     Home    Win