显示多索引 pandas 数据框的前 10 行
Show first 10 rows of multi-index pandas dataframe
我有一个多级索引 pandas DataFrame
,其中第一级是 year
,第二级是 username
。我只有一列已经按降序排列。我想显示每个索引级别 0 的前 2 行。
我有什么:
count
year username
2010 b 677
a 505
c 400
d 300
...
2014 a 100
b 80
我想要什么:
count
year username
2010 b 677
a 505
2011 c 677
d 505
2012 e 677
f 505
2013 g 677
i 505
2014 h 677
j 505
这是一个答案。也许有更好的方法来做到这一点(使用索引?),但我认为它有效。
原理看似复杂其实很简单:
- 按年份和用户名索引
DataFrame
。
- 按年份对
DataFrame
进行分组,这是索引的第一级 (=0
)
- 对
groupby
获得的子DataFrame
进行两次操作(每年一次)
- 按计数升序排列索引
sort_index(by='count')
->计数多的行将在DataFrame
的尾部
- 使用负切片符号 (
[-top:]
) 仅保留最后 top
行(在本例中为 2 行)。也可以使用 tail
方法 (tail(top)
) 来提高可读性。
- 删除为年份
droplevel(0)
创建的不必要的级别
# Test data
df = pd.DataFrame({'year': [2010, 2010, 2010, 2011,2011,2011, 2012, 2012, 2013, 2013, 2014, 2014],
'username': ['b','a','a','c','c','d','e','f','g','i','h','j'],
'count': [400, 505, 678, 677, 505, 505, 677, 505, 677, 505, 677, 505]})
df = df.set_index(['year','username'])
top = 2
df = df.groupby(level=0).apply(lambda df: df.sort_index(by='count')[-top:])
df.index = df.index.droplevel(0)
df
count
year username
2010 a 505
a 678
2011 d 505
c 677
2012 f 505
e 677
2013 i 505
g 677
2014 j 505
h 677
如果您有一个巨大的数据框,您可能不想 groupby
只是为了看一眼数据。这是获取外部索引的前五行和内部索引的前两行的另一种解决方案。
df = pd.DataFrame({'year': [2010, 2010, 2010, 2011,2011,2011, 2012, 2012, 2013, 2013, 2014, 2014],
'username': ['b','a','a','c','c','d','e','f','g','i','h','j'],
'count': [400, 505, 678, 677, 505, 505, 677, 505, 677, 505, 677, 505]})
df = df.set_index(['year','username'])
请注意 DataFrame
必须排序。
df = df.sort_index(level=[0,1])
df
count
year username
2010 a 505
a 678
b 400
2011 c 677
c 505
d 505
2012 e 677
f 505
2013 g 677
i 505
2014 h 677
j 505
现在开始魔术:
def head_mi(df, n1=5, n2=2):
#get top n of outer index
top_lev_0 = df.index.levels[0].values[:n1]
#get top n of inner index
top_lev_1 = [df.loc[ind].index.values[:n2] for ind in top_lev_0 ]
#top_lev_1 is a list of the inner index values
#iterate over outer index and get slice from inner index
acc = []
for count0, ind0 in enumerate(top_lev_0):
acc.append(df.loc[(top_lev_0[count0], slice(top_lev_1[count0][0], top_lev_1[count0][-1])),:])
return pd.concat(acc)
head_mi(df)
这给出:
count
year username
2010 a 505
a 678
2011 c 677
c 505
2012 e 677
f 505
2013 g 677
i 505
2014 h 677
j 505
我 运行 遇到了同样的问题,并在文档(pandas 版本 1.0.1)中找到了更简洁的答案:GroupBy: taking the first rows of each group。这是技巧,假设您的数据框被称为 df
:
df.groupby(level=0).head(2)
我有一个多级索引 pandas DataFrame
,其中第一级是 year
,第二级是 username
。我只有一列已经按降序排列。我想显示每个索引级别 0 的前 2 行。
我有什么:
count
year username
2010 b 677
a 505
c 400
d 300
...
2014 a 100
b 80
我想要什么:
count
year username
2010 b 677
a 505
2011 c 677
d 505
2012 e 677
f 505
2013 g 677
i 505
2014 h 677
j 505
这是一个答案。也许有更好的方法来做到这一点(使用索引?),但我认为它有效。 原理看似复杂其实很简单:
- 按年份和用户名索引
DataFrame
。 - 按年份对
DataFrame
进行分组,这是索引的第一级 (=0
) - 对
groupby
获得的子DataFrame
进行两次操作(每年一次)- 按计数升序排列索引
sort_index(by='count')
->计数多的行将在DataFrame
的尾部
- 使用负切片符号 (
[-top:]
) 仅保留最后top
行(在本例中为 2 行)。也可以使用tail
方法 (tail(top)
) 来提高可读性。
- 按计数升序排列索引
- 删除为年份
droplevel(0)
创建的不必要的级别
# Test data
df = pd.DataFrame({'year': [2010, 2010, 2010, 2011,2011,2011, 2012, 2012, 2013, 2013, 2014, 2014],
'username': ['b','a','a','c','c','d','e','f','g','i','h','j'],
'count': [400, 505, 678, 677, 505, 505, 677, 505, 677, 505, 677, 505]})
df = df.set_index(['year','username'])
top = 2
df = df.groupby(level=0).apply(lambda df: df.sort_index(by='count')[-top:])
df.index = df.index.droplevel(0)
df
count
year username
2010 a 505
a 678
2011 d 505
c 677
2012 f 505
e 677
2013 i 505
g 677
2014 j 505
h 677
如果您有一个巨大的数据框,您可能不想 groupby
只是为了看一眼数据。这是获取外部索引的前五行和内部索引的前两行的另一种解决方案。
df = pd.DataFrame({'year': [2010, 2010, 2010, 2011,2011,2011, 2012, 2012, 2013, 2013, 2014, 2014],
'username': ['b','a','a','c','c','d','e','f','g','i','h','j'],
'count': [400, 505, 678, 677, 505, 505, 677, 505, 677, 505, 677, 505]})
df = df.set_index(['year','username'])
请注意 DataFrame
必须排序。
df = df.sort_index(level=[0,1])
df
count
year username
2010 a 505
a 678
b 400
2011 c 677
c 505
d 505
2012 e 677
f 505
2013 g 677
i 505
2014 h 677
j 505
现在开始魔术:
def head_mi(df, n1=5, n2=2):
#get top n of outer index
top_lev_0 = df.index.levels[0].values[:n1]
#get top n of inner index
top_lev_1 = [df.loc[ind].index.values[:n2] for ind in top_lev_0 ]
#top_lev_1 is a list of the inner index values
#iterate over outer index and get slice from inner index
acc = []
for count0, ind0 in enumerate(top_lev_0):
acc.append(df.loc[(top_lev_0[count0], slice(top_lev_1[count0][0], top_lev_1[count0][-1])),:])
return pd.concat(acc)
head_mi(df)
这给出:
count
year username
2010 a 505
a 678
2011 c 677
c 505
2012 e 677
f 505
2013 g 677
i 505
2014 h 677
j 505
我 运行 遇到了同样的问题,并在文档(pandas 版本 1.0.1)中找到了更简洁的答案:GroupBy: taking the first rows of each group。这是技巧,假设您的数据框被称为 df
:
df.groupby(level=0).head(2)