pandas 在Python中仅知道开始和结束日期时构造面板数据/时间序列

smdncfj3  于 2023-02-06  发布在  Python
关注(0)|答案(2)|浏览(141)

假设我有表1中的信息,我打算使用Pandas的DataFrame将表1展开为表2。如果我使用Pandas自动生成结果而无需手动操作,您能否解释一下获得表2的过程?
欢迎任何建议。
日期格式为MM/YYYY。

    • 表一**

| 人|公司|开始日期|结束日期|
| - ------|- ------|- ------|- ------|
| 班先生|A公司|1984年8月|一九八四年十月|
| | B公司|1/1985|1985年3月|
预期结果如下所示。

    • 表二**

| 人|年份|公司|
| - ------|- ------|- ------|
| 班先生|1984年8月|A公司|
| | 一九八四年九月|A公司|
| | 一九八四年十月|A公司|
| | 一九八四年十一月|失业者|
| | 一九八四年十二月|失业者|
| | 1/1985|B公司|
| | 1985年2月|B公司|
| | 1985年3月|B公司|

sgtfey8w

sgtfey8w1#

Person列中可能存在多个Person的解:

df = pd.DataFrame([{'Person': 'Mr. Bun', 'Company': 'Company A', 
                    'Begin date': '8/1984', 'End Date': '10/1984'}, 
                   {'Person': np.nan, 'Company': 'Company B',
                    'Begin date': '1/1985', 'End Date': '3/1985'}])
    
print (df)
    Person    Company Begin date End Date
0  Mr. Bun  Company A     8/1984  10/1984
1      NaN  Company B     1/1985   3/1985
#forward filling missing values
df['Person'] = df['Person'].ffill()

#convert values to months periods
df['Begin date'] = pd.to_datetime(df['Begin date']).dt.to_period('m')
df['End Date'] = pd.to_datetime(df['End Date']).dt.to_period('m')

#repeat indices for difference of End and Begin months periods
df1 = df.loc[df.index.repeat(df['End Date'].astype(int)
                     .sub(df['Begin date'].astype(int)).add(1))]

#add counter to Begin date
df1['Year'] = df1['Begin date'].add(df1.groupby(level=0).cumcount())

#add Unemployed values for missing months
f = lambda x: x.reindex(pd.period_range(x.index.min(), x.index.max(), 
                                        freq='m', name='Year'), fill_value='Unemployed')
df1 = df1.set_index('Year').groupby('Person')['Company'].apply(f).reset_index()

#original format MM/YYYY
df1['Year'] = df1['Year'].dt.strftime('%m/%Y')

print (df1)
    Person     Year     Company
0  Mr. Bun  08/1984   Company A
1  Mr. Bun  09/1984   Company A
2  Mr. Bun  10/1984   Company A
3  Mr. Bun  11/1984  Unemployed
4  Mr. Bun  12/1984  Unemployed
5  Mr. Bun  01/1985   Company B
6  Mr. Bun  02/1985   Company B
7  Mr. Bun  03/1985   Company B
fdx2calv

fdx2calv2#

基本上,您可以使用类似下面的代码来加快处理速度:
数据:

df = pd.DataFrame({'name':['Bun', 'Bun'],
                   'comp':['A', 'B'],
                   'start': pd.to_datetime(['1984-08-31', '1985-01-31']),
                   'end':pd.to_datetime(['1984-10-31', '1985-03-31'])})

创建new Dataframe 以填充所有日期

new = df[['name', 'start']].set_index(['name', 'start'])
mux = pd.MultiIndex.from_product([new.index.levels[0], pd.date_range(start='1984-08-31', end='1985-03-31', freq='M')], names=['name', 'date'])
new.reindex(mux).reset_index()

其输出应为:

name       date
0  Bun 1984-08-31
1  Bun 1984-09-30
2  Bun 1984-10-31
3  Bun 1984-11-30
4  Bun 1984-12-31
5  Bun 1985-01-31
6  Bun 1985-02-28
7  Bun 1985-03-31

之后,可以将mergedf合并,然后删除不必要的行

相关问题