python - Pandas 的自定义财政季度?

标签 python pandas

我正在处理面板数据,其中我有几家上市公司和每家公司的几个季度观察结果。我认为组织数据的最佳方式是 MultiIndex,其中第一级是唯一的公司标识符(在本例中为“gvkey”),第二级是季度。

我很难弄清楚如何做到这一点,因为财政年度结束可以是一年中的任何一个月,这表明我无法使用 DatetimeIndex.quarter。有没有办法让我在 Pandas 中定义对 Pandas 有意义的自定义区域?我可以简单地使用一个字符串,例如“2014Q1”,但我希望它能够成为某种对象,以便 Pandas 知道上一季度是什么,或者知道该公司的财政年度结束时间是第 10 个月,所以 2014Q1 将在 2014 年 1 月结束。这可能吗?

这是我在 DataFrame 中拥有的一些数据的示例。索引是gvkey,一个唯一的公司标识符。 datadate 是季度的最后一天(即季度最后一个月的最后一天),datafqtr 是字符串形式的年份和季度,fyr 是财政年度结束的月份(例如,5 表示该年度在 5 月结束)。

        conm    datadate    datafqtr    fyr
gvkey               
001004  AAR CORP    2014-02-28  2013Q3  5.0
001004  AAR CORP    2014-05-31  2013Q4  5.0
001004  AAR CORP    2014-08-31  2014Q1  5.0
001004  AAR CORP    2014-11-30  2014Q2  5.0
001045  AMERICAN AIRLINES GROUP INC 2014-03-31  2014Q1  12.0
001045  AMERICAN AIRLINES GROUP INC 2014-06-30  2014Q2  12.0
001045  AMERICAN AIRLINES GROUP INC 2014-09-30  2014Q3  12.0
001045  AMERICAN AIRLINES GROUP INC 2014-12-31  2014Q4  12.0
001050  CECO ENVIRONMENTAL CORP 2014-03-31  2014Q1  12.0
001050  CECO ENVIRONMENTAL CORP 2014-06-30  2014Q2  12.0
001050  CECO ENVIRONMENTAL CORP 2014-09-30  2014Q3  12.0
001050  CECO ENVIRONMENTAL CORP 2014-12-31  2014Q4  12.0
001062  ASA GOLD AND PRECIOUS METALS    2014-02-28  2014Q1  11.0
001062  ASA GOLD AND PRECIOUS METALS    2014-05-31  2014Q2  11.0
001062  ASA GOLD AND PRECIOUS METALS    2014-08-31  2014Q3  11.0
001062  ASA GOLD AND PRECIOUS METALS    2014-11-30  2014Q4  11.0
001072  AVX CORP    2014-03-31  2013Q4  3.0
001072  AVX CORP    2014-06-30  2014Q1  3.0
001072  AVX CORP    2014-09-30  2014Q2  3.0
001072  AVX CORP    2014-12-31  2014Q3  3.0

最佳答案

经过一些挠头,我想我知道你在问什么。

首先,我会制作一些数据:

# Make dataframe
df = pd.DataFrame({'gvkey' : ['001004']*4 +\
                             ['001045']*4 +\
                             ['001050']*4 +\
                             ['001062']*4 +\
                             ['001072']*4,
                   'conm' : ['AAR CORP']*4 +\
                            ['AMERICAN AIRLINES GROUP INC']*4 +\
                            ['CECO ENVIRONMENTAL CORP']*4 +\
                            ['ASA GOLD AND PRECIOUS METALS']*4 +\
                            ['AVX CORP']*4,
                   'datadate' : ['2014-02-28', '2014-05-31', '2014-08-31', '2014-11-30'] +\
                                ['2014-03-31', '2014-06-30', '2014-09-30', '2014-12-31']*2 +\
                                ['2014-02-28', '2014-05-31', '2014-08-31', '2014-11-30'] +\
                                ['2014-03-31', '2014-06-30', '2014-09-30', '2014-12-31'],
                   'datafqtr' : ['2013Q3', '2013Q4', '2014Q1', '2014Q2'] +\
                               ['2014Q1', '2014Q2', '2014Q3', '2014Q4']*3 +\
                               ['2013Q4', '2014Q1', '2014Q2', '2014Q3'],
                   'fyr' : [5]*4 +\
                           [12]*8 +\
                           [11]*4 +\
                           [3]*4})

# Reorder columns
df = df[[df.columns[-1]] + list(df.columns[:-1])]

# Convert 'datadate' to datetime
df.loc[:, 'datadate'] = pd.to_datetime(df.loc[:, 'datadate'])

# Show the dataframe
df

original df

其次,(根据我对问题的解释)我将创建您的 datafqtr 列的副本。为此,我使用了模 12 映射技术来创建季度和年份:

# Copy the dataframe
df1 = df.copy()

# Insert 'year' column
df1.insert(df1.shape[1],
           'year',
           df1.loc[:, 'datadate'].dt.year)

# Insert 'month' column
df1.insert(df1.shape[1],
           'month',
           df1.loc[:, 'datadate'].dt.month)

# Subtract 'fyr' from 'month'
df1.insert(df1.shape[1],
           'month-fyr',
           df1.loc[:, 'month'] - df1.loc[:, 'fyr'])

# Create 'new_year' column
df1.insert(df1.shape[1],
           'new_year',
           np.where((df1.loc[:, 'month-fyr'] <= 0) & (df1.loc[:, 'fyr'] < 6),
                    df1.loc[:, 'year'] - 1,
                    df1.loc[:, 'year']))

# Make a mapper for mapping the values of 'month-fyr' to 'new_qtr'
mapper = {-9 : 1,
          -6 : 2,
          -3 : 3,
          0 : 4,
          3 : 1,
          6 : 2,
          9 : 3}

# Insert the 'new_qtr' column
df1.insert(df1.shape[1],
           'new_qtr',
           df1.loc[:, 'month-fyr'].map(mapper))

# Insert 'new_datafqtr' column (this should be equivalent to 'datafqtr')
df1.insert(df1.shape[1],
           'new_datafqtr',
           df1.loc[:, 'new_year'].astype(str) + 'Q' + df1.loc[:, 'new_qtr'].astype(str))

# Show the dataframe
df1

new df

请注意,当我创建 'new_year' 列时,我必须考虑 'fyr' 是否小于 6。这对于创建列很重要。

如果您想按 'gvkey'、'conm'、'new_year'、'new_qtr' 分组,这将显示正确的财政年度和季度(按顺序)。

希望这对您有所帮助!

编辑:

# Insert random revenue
df1.insert(df1.shape[1],
           'random_revenue',
           np.random.randint(low = 0, high = 1000000, size = df1.shape[0]))

# Groupby 'gvkey', 'conm', 'new_year', 'new_qtr' and sum 'random_revenue'
df_group = df1.groupby(['gvkey',
                        'conm',
                        'new_year',
                        'new_qtr']).agg({'random_revenue' : 'sum'})

# Find difference in revenue for "AAR CORP" between 2013Q3 and 2014Q2
df_group.loc[('001004', 'AAR CORP', slice(None), [3, 2])].diff()

pd.diff() 的文档 --> https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.diff.html#pandas-dataframe-diff

关于python - Pandas 的自定义财政季度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46417735/

相关文章:

python - 字幕中的多种尺寸字体

python - 使用 vispy 绘制 3d 隐式方程

python - 重试 MySQL/SQLAlchemy 的死锁

python - 使用条件语句替换 pandas DataFrame 中的条目

python - 使用 Pandas 在同一图中绘制分组数据

python - 为什么 pandas.cut() 在两种类似情况下的唯一计数表现不同?

python - Pandas:为每行查找列名和具有最大(和第二个最大)值的值

python - 如何使用 matplotlib 绘制盒须图

python - 将 3 维数组转换为 2 维数组

python - PyQt4 需要将 DLL 移动到包根目录