Python Pandas-查找多索引中某一级别值最小的行

Python Pandas-查找多索引中某一级别值最小的行,python,pandas,dataframe,Python,Pandas,Dataframe,因此,我有一个带有多索引的数据帧,它看起来像这样: info1 info2 info3 abc-8182 2012-05-08 10:00:00 1 6.0 "yeah!" 2012-05-08 10:01:00 2 25.0 ":(" pli-9230 2012-05-08 11:00:00 1 30.0 "see yah!"

因此,我有一个带有多索引的数据帧,它看起来像这样:

                               info1 info2       info3
abc-8182 2012-05-08 10:00:00       1   6.0     "yeah!"
         2012-05-08 10:01:00       2  25.0        ":("
pli-9230 2012-05-08 11:00:00       1  30.0  "see yah!"    
         2012-05-08 11:15:00       1  30.0  "see yah!"    

...
索引是一个id和一个日期时间,表示记录有关该id的信息的时间。我们需要做的是为每个id找到最早的记录。我们从dataframe方法中尝试了很多选项,但最终通过循环数据帧来实现:

df = pandas.read_csv(...)
empty = pandas.DataFrame()
ids = df.index.get_level_values(0)
for id in ids:
    minDate  = df.xs(id).index.min()
    row = df.xs(id).xs(minDate)
    mindf = pandas.DataFrame(row).transpose()
    mindf.index = pandas.MultiIndex.from_tuples([(id, mindate)])
    empty = empty.append(mindf)

print empty.groupby(lambda x : x).first()
这给了我:

                                               x0  x1        x2
('abc-8182', <Timestamp: 2012-05-08 10:00:00>)  1   6     yeah!
('pli-9230', <Timestamp: 2012-05-08 11:00:00>)  1  30  see yah!
x0-x1-x2
('abc-8182',)16耶!
(‘pli-9230’,)130见耶!
我觉得必须有一种简单的“熊猫习语”,非常直接的方法来做到这一点,而不必像这样在数据帧中循环。有吗?:)


谢谢。

要获得每组中的第一项,您可以执行以下操作:

df.reset_index(level=1).groupby(level=0).first()
这将在按groupby对组进行分组之前将datetime字段删除到列中,因此它将保留在结果的数据帧中

如果需要确保保留最早的时间,可以在首先调用
之前进行排序:

df.reset_index(level=1).sort_index(by="datetime").groupby(level=0).first()

要获取每组中的第一项,您可以执行以下操作:

df.reset_index(level=1).groupby(level=0).first()
这将在按groupby对组进行分组之前将datetime字段删除到列中,因此它将保留在结果的数据帧中

如果需要确保保留最早的时间,可以在首先调用
之前进行排序:

df.reset_index(level=1).sort_index(by="datetime").groupby(level=0).first()


你在开玩笑,就这么简单!!哈哈哈。即使日期没有排序?有没有办法对它们进行排序?我试过了,但它只是返回了完全相同的数据帧。如果我使用
df.sort().groupby(level=[0]).first()
它有点像我想要的,但是我丢失了我需要的日期信息。如果你有一个多索引,其中level 0有'abc-8182'这样的值,level 1有timeseries值,那么上面的代码应该删除重复的行,并在你的示例中保留第一行。你是说那没有发生?没有。检查groupby的结果,我在每个组中都有一个项目。由于每个索引项都是唯一的(每个id只有一个datetime),因此两个级别的分组似乎都会导致这种情况。我认为我们正在研究不同的数据帧。如果每个索引都是唯一的,则按两个索引进行分组肯定只会在每个组中包含一项。如果是这样的话,如果这是您想要的结果,那么改为按级别分组=0。对不起,如果我误解了你的意思。你在开玩笑,就是这么简单!!哈哈哈。即使日期没有排序?有没有办法对它们进行排序?我试过了,但它只是返回了完全相同的数据帧。如果我使用
df.sort().groupby(level=[0]).first()
它有点像我想要的,但是我丢失了我需要的日期信息。如果你有一个多索引,其中level 0有'abc-8182'这样的值,level 1有timeseries值,那么上面的代码应该删除重复的行,并在你的示例中保留第一行。你是说那没有发生?没有。检查groupby的结果,我在每个组中都有一个项目。由于每个索引项都是唯一的(每个id只有一个datetime),因此两个级别的分组似乎都会导致这种情况。我认为我们正在研究不同的数据帧。如果每个索引都是唯一的,则按两个索引进行分组肯定只会在每个组中包含一项。如果是这样的话,如果这是您想要的结果,那么改为按级别分组=0。抱歉,如果我误解了您的目的。如果您的数据已经按照此处所示及时排序[-然后删除重复项自动选择重复行中的“第一个”我必须通过列才能删除重复项,对吗?但是我要删除的重复项位于索引的某个级别,而不是列。我做了
df['id']=df.index.get_level_values(0)
df.drop_duplicates('id')
有效。它更好,但感觉还是很粗糙。df.reset_index()会将索引值作为列插入。但我同意下面的答案似乎更正确这正是我需要的:
df2.reset_index()。set_index('id')。sort('datetime')。groupby(lambda x:x).agg(lambda x:x[0])
如果您的数据已按此处所示及时排序[-然后删除重复项自动选择重复行中的“第一个”我必须通过列才能删除重复项,对吗?但我要删除的重复项位于索引的一个级别,而不是列。我做了
df['id']=df.index.get_level_values(0)
df.drop_duplicates('id')
有效。它更好,但感觉还是很粗糙。df.reset_index()会将索引值作为列插入。但我同意下面的答案似乎更正确这正是我需要的:
df2.reset_index()。set_index('id')。sort('datetime')。groupby(λx:x).agg(λx:x[0])