修改特定组的 pandas 多索引值
Modify pandas multiindex value for a particular group
假设我有一个 pandas 具有三个不同级别的 MultiIndex DataFrame:
arrays = [['2020-03-30', '2020-03-30', '2020-03-30', '2020-04-15', '2020-04-15', '2020-04-15', '2020-05-10', '2020-05-10', '2020-06-10'], ['Firm1', 'Firm1', 'Firm2', 'Firm1', 'Firm2', 'Firm2', 'Firm1', 'Firm1', 'Firm1'], ['2022-01-01', '2023-02-01', '2021-01-05', '2021-04-01', '2022-01-01', '2024-02-01', '2021-02-05', '2022-04-01', '2022-04-01']]
idx = pd.MultiIndex.from_arrays(arrays, names = ('Buy_date', 'Firm', 'Sell_date'))
df = pd.DataFrame(np.zeros(9), index = idx)
df
0
Buy_date Firm Sell_date
2020-03-30 Firm1 2022-01-01 0.0
2023-02-01 0.0
Firm2 2021-01-05 0.0
2020-04-15 Firm1 2021-04-01 0.0
Firm2 2022-01-01 0.0
2024-02-01 0.0
2020-05-10 Firm1 2021-02-05 0.0
2022-04-01 0.0
2020-06-10 Firm1 2022-04-01 0.0
对于给定的买入日期,我想更改公司 1 的最大 Sell_date 指数值并将其设置为 01.01.2030。所以输出应该是:
Buy_date Firm Sell_date
2020-03-30 Firm1 2022-01-01 0.0
2030-01-01 0.0
Firm2 2021-01-05 0.0
2020-04-15 Firm1 2030-01-01 0.0
Firm2 2022-01-01 0.0
2024-02-01 0.0
2020-05-10 Firm1 2021-02-05 0.0
2030-01-01 0.0
2020-06-10 Firm1 2030-01-01 0.0
有人知道怎么做吗?
这是使用 set_index
的一种方法,并附加一个具有所需修改的新索引级别。还使用 groupby.transform
获取最大日期:
max_dates = df.reset_index(level='Sell_date').groupby(level=[0,1])['Sell_date'].transform('max')
df = df.set_index(df.index.get_level_values(2)
.where((df.index.get_level_values(1)!='Firm1') |
(df.index.get_level_values(2)!=max_dates), '2030-01-01'),
append=True).droplevel(2)
更直接的方法是使用 reset_index
,修改 DataFrame 并使用新列设置索引:
df1 = df.reset_index()
max_date = df1.groupby(['Buy_date','Firm'])['Sell_date'].transform('max')
df1.loc[df1['Sell_date'].eq(max_date) & df1['Firm'].eq('Firm1'), 'Sell_date'] = '2030-01-01'
df = df1.set_index(['Buy_date','Firm','Sell_date'])
输出:
0
Buy_date Firm Sell_date
2020-03-30 Firm1 2022-01-01 0.0
2030-01-01 0.0
Firm2 2021-01-05 0.0
2020-04-15 Firm1 2030-01-01 0.0
Firm2 2022-01-01 0.0
2024-02-01 0.0
2020-05-10 Firm1 2021-02-05 0.0
2030-01-01 0.0
2020-06-10 Firm1 2030-01-01 0.0
假设我有一个 pandas 具有三个不同级别的 MultiIndex DataFrame:
arrays = [['2020-03-30', '2020-03-30', '2020-03-30', '2020-04-15', '2020-04-15', '2020-04-15', '2020-05-10', '2020-05-10', '2020-06-10'], ['Firm1', 'Firm1', 'Firm2', 'Firm1', 'Firm2', 'Firm2', 'Firm1', 'Firm1', 'Firm1'], ['2022-01-01', '2023-02-01', '2021-01-05', '2021-04-01', '2022-01-01', '2024-02-01', '2021-02-05', '2022-04-01', '2022-04-01']]
idx = pd.MultiIndex.from_arrays(arrays, names = ('Buy_date', 'Firm', 'Sell_date'))
df = pd.DataFrame(np.zeros(9), index = idx)
df
0
Buy_date Firm Sell_date
2020-03-30 Firm1 2022-01-01 0.0
2023-02-01 0.0
Firm2 2021-01-05 0.0
2020-04-15 Firm1 2021-04-01 0.0
Firm2 2022-01-01 0.0
2024-02-01 0.0
2020-05-10 Firm1 2021-02-05 0.0
2022-04-01 0.0
2020-06-10 Firm1 2022-04-01 0.0
对于给定的买入日期,我想更改公司 1 的最大 Sell_date 指数值并将其设置为 01.01.2030。所以输出应该是:
Buy_date Firm Sell_date
2020-03-30 Firm1 2022-01-01 0.0
2030-01-01 0.0
Firm2 2021-01-05 0.0
2020-04-15 Firm1 2030-01-01 0.0
Firm2 2022-01-01 0.0
2024-02-01 0.0
2020-05-10 Firm1 2021-02-05 0.0
2030-01-01 0.0
2020-06-10 Firm1 2030-01-01 0.0
有人知道怎么做吗?
这是使用 set_index
的一种方法,并附加一个具有所需修改的新索引级别。还使用 groupby.transform
获取最大日期:
max_dates = df.reset_index(level='Sell_date').groupby(level=[0,1])['Sell_date'].transform('max')
df = df.set_index(df.index.get_level_values(2)
.where((df.index.get_level_values(1)!='Firm1') |
(df.index.get_level_values(2)!=max_dates), '2030-01-01'),
append=True).droplevel(2)
更直接的方法是使用 reset_index
,修改 DataFrame 并使用新列设置索引:
df1 = df.reset_index()
max_date = df1.groupby(['Buy_date','Firm'])['Sell_date'].transform('max')
df1.loc[df1['Sell_date'].eq(max_date) & df1['Firm'].eq('Firm1'), 'Sell_date'] = '2030-01-01'
df = df1.set_index(['Buy_date','Firm','Sell_date'])
输出:
0
Buy_date Firm Sell_date
2020-03-30 Firm1 2022-01-01 0.0
2030-01-01 0.0
Firm2 2021-01-05 0.0
2020-04-15 Firm1 2030-01-01 0.0
Firm2 2022-01-01 0.0
2024-02-01 0.0
2020-05-10 Firm1 2021-02-05 0.0
2030-01-01 0.0
2020-06-10 Firm1 2030-01-01 0.0