Pandas:在 MultiIndex 数据帧中的每个索引后添加一个空行
Pandas: Add an empty row after every index in a MultiIndex dataframe
考虑以下 df
:
IA1 IA2 IA3
Name Subject
Abc DS 45 43 34
DMS 43 23 45
ADA 32 46 36
Bcd BA 45 35 37
EAD 23 45 12
DS 23 35 43
Cdf EAD 34 33 23
ADA 12 34 25
如何在每个 Name
索引后添加一个空行?
预期输出:
IA1 IA2 IA3
Name Subject
Abc DS 45 43 34
DMS 43 23 45
ADA 32 46 36
Bcd BA 45 35 37
EAD 23 45 12
DS 23 35 43
Cdf EAD 34 33 23
ADA 12 34 25
使用自定义函数在 GroupBy.apply
中添加空行:
def f(x):
x.loc[('', ''), :] = ''
return x
或者:
def f(x):
return x.append(pd.DataFrame('', columns=df.columns, index=[(x.name, '')]))
df = df.groupby(level=0, group_keys=False).apply(f)
print (df)
IA1 IA2 IA3
Name Subject
Abc DS 45 43 34
DMS 43 23 45
ADA 32 46 36
Bcd BA 45 35 37
EAD 23 45 12
DS 23 35 43
Cdf EAD 34 33 23
ADA 12 34 25
使用df.reindex
and fill_value
as ''
after using pd.MultiIndex.from_product
and Index.union
添加另一种方式,然后对其进行排序。
idx = df.index.union(pd.MultiIndex.from_product((df.index.levels[0],[''])),sort=False)
out = df.reindex(sorted(idx,key=lambda x: x[0]),fill_value='')
print(out)
IA1 IA2 IA3
Name Subject
Abc DS 45 43 34
DMS 43 23 45
ADA 32 46 36
Bcd BA 45 35 37
EAD 23 45 12
DS 23 35 43
Cdf EAD 34 33 23
ADA 12 34 25
我们在使用 Index.union
索引时使用 sort=False
以便保留顺序,然后在第一个元素上使用 sorted
returns:
sorted(idx,key=lambda x:x[0])
[('Abc', 'DS'),
('Abc', 'DMS'),
('Abc', 'ADA'),
('Abc', ''),
('Bcd', 'BA'),
('Bcd', 'EAD'),
('Bcd', 'DS'),
('Bcd', ''),
('Cdf', 'EAD'),
('Cdf', 'ADA'),
('Cdf', '')]
# reset index
dfn = df.reset_index()
# find the border idx of 'Name', [2, 5, 7]
idx_list = dfn.drop_duplicates('Name', keep='last').index
# use the border idx, create an empty df, and append to the origin df, then sort the index
df_append = pd.DataFrame('', index = idx_list, columns = dfn.columns)
obj = dfn.append(df_append).sort_index().set_index(['Name', 'Subject'])
print(obj)
IA1 IA2 IA3
Name Subject
Abc DS 45 43 34
DMS 43 23 45
ADA 32 46 36
Bcd BA 45 35 37
EAD 23 45 12
DS 23 35 43
Cdf EAD 34 33 23
ADA 12 34 25
考虑以下 df
:
IA1 IA2 IA3
Name Subject
Abc DS 45 43 34
DMS 43 23 45
ADA 32 46 36
Bcd BA 45 35 37
EAD 23 45 12
DS 23 35 43
Cdf EAD 34 33 23
ADA 12 34 25
如何在每个 Name
索引后添加一个空行?
预期输出:
IA1 IA2 IA3
Name Subject
Abc DS 45 43 34
DMS 43 23 45
ADA 32 46 36
Bcd BA 45 35 37
EAD 23 45 12
DS 23 35 43
Cdf EAD 34 33 23
ADA 12 34 25
使用自定义函数在 GroupBy.apply
中添加空行:
def f(x):
x.loc[('', ''), :] = ''
return x
或者:
def f(x):
return x.append(pd.DataFrame('', columns=df.columns, index=[(x.name, '')]))
df = df.groupby(level=0, group_keys=False).apply(f)
print (df)
IA1 IA2 IA3
Name Subject
Abc DS 45 43 34
DMS 43 23 45
ADA 32 46 36
Bcd BA 45 35 37
EAD 23 45 12
DS 23 35 43
Cdf EAD 34 33 23
ADA 12 34 25
使用df.reindex
and fill_value
as ''
after using pd.MultiIndex.from_product
and Index.union
添加另一种方式,然后对其进行排序。
idx = df.index.union(pd.MultiIndex.from_product((df.index.levels[0],[''])),sort=False)
out = df.reindex(sorted(idx,key=lambda x: x[0]),fill_value='')
print(out)
IA1 IA2 IA3
Name Subject
Abc DS 45 43 34
DMS 43 23 45
ADA 32 46 36
Bcd BA 45 35 37
EAD 23 45 12
DS 23 35 43
Cdf EAD 34 33 23
ADA 12 34 25
我们在使用 Index.union
索引时使用 sort=False
以便保留顺序,然后在第一个元素上使用 sorted
returns:
sorted(idx,key=lambda x:x[0])
[('Abc', 'DS'),
('Abc', 'DMS'),
('Abc', 'ADA'),
('Abc', ''),
('Bcd', 'BA'),
('Bcd', 'EAD'),
('Bcd', 'DS'),
('Bcd', ''),
('Cdf', 'EAD'),
('Cdf', 'ADA'),
('Cdf', '')]
# reset index
dfn = df.reset_index()
# find the border idx of 'Name', [2, 5, 7]
idx_list = dfn.drop_duplicates('Name', keep='last').index
# use the border idx, create an empty df, and append to the origin df, then sort the index
df_append = pd.DataFrame('', index = idx_list, columns = dfn.columns)
obj = dfn.append(df_append).sort_index().set_index(['Name', 'Subject'])
print(obj)
IA1 IA2 IA3
Name Subject
Abc DS 45 43 34
DMS 43 23 45
ADA 32 46 36
Bcd BA 45 35 37
EAD 23 45 12
DS 23 35 43
Cdf EAD 34 33 23
ADA 12 34 25