gpt4 book ai didi

python - 如何获取 pandas 数据框中的行,列中有最大值并保留原始索引?

转载 作者:太空宇宙 更新时间:2023-11-03 14:25:55 27 4
gpt4 key购买 nike

我有一个 Pandas 数据框。在第一列中,它可以多次具有相同的值(换句话说,第一列中的值不是唯一的)。

每当我有几行在第一列中包含相同的值时,我想只在第三列中保留那些具有最大值的行。我几乎找到了解决方案:

import pandas

ls = []
ls.append({'c1':'a', 'c2':'a', 'c3':1})
ls.append({'c1':'a', 'c2':'c', 'c3':3})
ls.append({'c1':'a', 'c2':'b', 'c3':2})
ls.append({'c1':'b', 'c2':'b', 'c3':10})
ls.append({'c1':'b', 'c2':'c', 'c3':12})
ls.append({'c1':'b', 'c2':'a', 'c3':7})

df = pandas.DataFrame(ls, columns=['c1','c2','c3'])
print df
print '--------------------'
print df.groupby('c1').apply(lambda df:df.irow(df['c3'].argmax()))

结果我得到:

  c1 c2  c3
0 a a 1
1 a c 3
2 a b 2
3 b b 10
4 b c 12
5 b a 7
--------------------
c1 c2 c3
c1
a a c 3
b b c 12

我的问题是,我不想将 c1 作为索引。我想要的是:

  c1 c2  c3
1 a c 3
4 b c 12

最佳答案

调用 df.groupby(...).apply(foo) 时,foo 返回的对象类型会影响结果融合在一起的方式。

如果您返回一个系列,系列的索引成为最终结果的列,groupby 键成为索引(有点令人费解)。

如果相反,您返回一个 DataFrame,最终结果将使用 DataFrame 的索引作为索引值,并将 DataFrame 的列作为列(非常明智)。

因此,您可以通过将 Series 转换为 DataFrame 来安排所需的输出类型。

在 Pandas 0.13 中,您可以使用 to_frame().T 方法:

def maxrow(x, col):
return x.loc[x[col].argmax()].to_frame().T

result = df.groupby('c1').apply(maxrow, 'c3')
result = result.reset_index(level=0, drop=True)
print(result)

产量

  c1 c2  c3
1 a c 3
4 b c 12

在 Pandas 0.12 或更早版本中,等同于:

def maxrow(x, col):
ser = x.loc[x[col].idxmax()]
df = pd.DataFrame({ser.name: ser}).T
return df

顺便说一下,behzad.nouri's clever and elegant solution对于小型 DataFrame,它比我的更快。sort 将时间复杂度从 O(n) 提升到 O(n log n) 但是,它变得比 慢to_frame 解决方案适用于较大的 DataFrame。

以下是我对其进行基准测试的方式:

import pandas as pd
import numpy as np
import timeit


def reset_df_first(df):
df2 = df.reset_index()
result = df2.groupby('c1').apply(lambda x: x.loc[x['c3'].idxmax()])
result.set_index(['index'], inplace=True)
return result

def maxrow(x, col):
result = x.loc[x[col].argmax()].to_frame().T
return result

def using_to_frame(df):
result = df.groupby('c1').apply(maxrow, 'c3')
result.reset_index(level=0, drop=True, inplace=True)
return result

def using_sort(df):
return df.sort('c3').groupby('c1', as_index=False).tail(1)


for N in (100, 1000, 2000):
df = pd.DataFrame({'c1': {0: 'a', 1: 'a', 2: 'a', 3: 'b', 4: 'b', 5: 'b'},
'c2': {0: 'a', 1: 'c', 2: 'b', 3: 'b', 4: 'c', 5: 'a'},
'c3': {0: 1, 1: 3, 2: 2, 3: 10, 4: 12, 5: 7}})

df = pd.concat([df]*N)
df.reset_index(inplace=True, drop=True)

timing = dict()
for func in (reset_df_first, using_to_frame, using_sort):
timing[func] = timeit.timeit('m.{}(m.df)'.format(func.__name__),
'import __main__ as m ',
number=10)

print('For N = {}'.format(N))
for func in sorted(timing, key=timing.get):
print('{:<20}: {:<0.3g}'.format(func.__name__, timing[func]))
print

产量

For N = 100
using_sort : 0.018
using_to_frame : 0.0265
reset_df_first : 0.0303

For N = 1000
using_to_frame : 0.0358 \
using_sort : 0.036 / this is roughly where the two methods cross over in terms of performance
reset_df_first : 0.0432

For N = 2000
using_to_frame : 0.0457
reset_df_first : 0.0523
using_sort : 0.0569

(reset_df_first 是我尝试过的另一种可能性。)

关于python - 如何获取 pandas 数据框中的行,列中有最大值并保留原始索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20703599/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com