使用级别获取多索引 Pandas DataFrame 的最小索引
Get index of the minimum of multi-index Pandas DataFrame using level
我有一个Pandas DataFrame that is multiindexed,想在每个级别的行子集中找到特定列的最小值,并获取这些行的全部内容。
import pandas as pd
idx = pd.MultiIndex.from_product([['v1', 'v2'],
['record' + str(i) for i in range(1, 7)]])
df = pd.DataFrame([[2., 114], [2., 1140],
[3., 114], [3., 1140],
[5., 114], [5., 1140],
[2., 114], [2., 1140],
[3., 114], [3., 1140],
[5., 114], [5., 1140]],
columns=['col1', 'col2'],
index=idx)
我的结构:
col1 col2
level1 level2
v1 record1 2.0 114
record2 2.0 1140
record3 3.0 114
record4 3.0 1140
record5 5.0 114
record6 5.0 1140
v2 record1 2.0 114
record2 2.0 1140
record3 3.0 114
record4 3.0 1140
record5 5.0 114
record6 5.0 1140
示例所需输出我想要另一列的最小值,其中 col1 == 5
:
col1 col2
level1 level2
v1 record5 5.0 114
v2 record5 5.0 114
我知道我可以使用比较语句获取行的子集。
df.ix[df['col1'] == 5]
而且我也知道我可以从 所有级别.[=22= 中获取该子集中列的最小 值 ]
df['col2'][df['col1'] == 5].min(level='level1')
如果我想指定级别,那么我可以在特定级别上获取1行的索引。
df.ix['v1', pay_up_file.ix['v1']['col2'][(df.ix['v1']['col1'] == 5)].idxmin()]
但我不知道是否有一种有效的方法可以从所有级别
获取索引
似乎没有可用的方法:
df['col2'][df['col1'] == 5].idxmin(level='level1')
我可以用这个得到我想要的:
df.ix[
(df['col1'] == 5) &
(df['col2'].isin(df['col2'][df['col1'] == 5].min(level='level1').values))
]
但是对于 Pandas
中的所有其他内容,是否有更好的方法来获取我的输出?
这应该有效:
df.loc[df.loc[df.col1 == 5.].groupby(level=0).col2.idxmin()]
col1 col2
v1 record5 5.0 114
v2 record5 5.0 114
备注
我正在使用 idxmin
,正如您认为您应该使用的那样。但上下文很重要。我在 groupby(level=0).col2.idxmin()
之后使用它,它按照您认为 col2.idxmin(level=...)
应该的方式运行。
>>> (df[df.col1 == 5]
.groupby(level=0, as_index=False).col2
.apply(lambda group: group.nsmallest(1))
0 v1 record5 114
1 v2 record5 114
dtype: int64
或者...
>>> df[df.col1 == 5].groupby(level=0).col2.nsmallest(1)
v1 v1 record5 114
v2 v2 record5 114
dtype: int64
但我不确定为什么第一级显示两次(即 'v1' 'v1' ...)。
我有一个Pandas DataFrame that is multiindexed,想在每个级别的行子集中找到特定列的最小值,并获取这些行的全部内容。
import pandas as pd
idx = pd.MultiIndex.from_product([['v1', 'v2'],
['record' + str(i) for i in range(1, 7)]])
df = pd.DataFrame([[2., 114], [2., 1140],
[3., 114], [3., 1140],
[5., 114], [5., 1140],
[2., 114], [2., 1140],
[3., 114], [3., 1140],
[5., 114], [5., 1140]],
columns=['col1', 'col2'],
index=idx)
我的结构:
col1 col2
level1 level2
v1 record1 2.0 114
record2 2.0 1140
record3 3.0 114
record4 3.0 1140
record5 5.0 114
record6 5.0 1140
v2 record1 2.0 114
record2 2.0 1140
record3 3.0 114
record4 3.0 1140
record5 5.0 114
record6 5.0 1140
示例所需输出我想要另一列的最小值,其中 col1 == 5
:
col1 col2
level1 level2
v1 record5 5.0 114
v2 record5 5.0 114
我知道我可以使用比较语句获取行的子集。
df.ix[df['col1'] == 5]
而且我也知道我可以从 所有级别.[=22= 中获取该子集中列的最小 值 ]
df['col2'][df['col1'] == 5].min(level='level1')
如果我想指定级别,那么我可以在特定级别上获取1行的索引。
df.ix['v1', pay_up_file.ix['v1']['col2'][(df.ix['v1']['col1'] == 5)].idxmin()]
但我不知道是否有一种有效的方法可以从所有级别
获取索引似乎没有可用的方法:
df['col2'][df['col1'] == 5].idxmin(level='level1')
我可以用这个得到我想要的:
df.ix[
(df['col1'] == 5) &
(df['col2'].isin(df['col2'][df['col1'] == 5].min(level='level1').values))
]
但是对于 Pandas
中的所有其他内容,是否有更好的方法来获取我的输出?
这应该有效:
df.loc[df.loc[df.col1 == 5.].groupby(level=0).col2.idxmin()]
col1 col2
v1 record5 5.0 114
v2 record5 5.0 114
备注
我正在使用 idxmin
,正如您认为您应该使用的那样。但上下文很重要。我在 groupby(level=0).col2.idxmin()
之后使用它,它按照您认为 col2.idxmin(level=...)
应该的方式运行。
>>> (df[df.col1 == 5]
.groupby(level=0, as_index=False).col2
.apply(lambda group: group.nsmallest(1))
0 v1 record5 114
1 v2 record5 114
dtype: int64
或者...
>>> df[df.col1 == 5].groupby(level=0).col2.nsmallest(1)
v1 v1 record5 114
v2 v2 record5 114
dtype: int64
但我不确定为什么第一级显示两次(即 'v1' 'v1' ...)。