在熊猫中分组为最小值后,如何完全沿 min() 值显示匹配的行结果

数据挖掘 Python 熊猫 数据框
2021-09-20 02:00:09

数据框包含

>> df
        A          B            C
A
196512  196512    1325  12.9010511000000
196512  196512  114569  12.9267705000000
196512  196512  118910  12.8983353775637
196512  196512  100688  12.9505091000000
196795  196795   28978  12.7805170314276
196795  196795   34591  12.8994111000000
196795  196795   13078  12.9135746000000
196795  196795   24173  12.8769653100000
196341  196341  118910  12.8983353775637
196341  196341  100688  12.9505091000000
196641  196641   28972  12.7805170314276
196641  196641   34591  12.8994111000000
196346  196341  118910  12.8983353775637
196346  196341  100688  12.9505091000000
196646  196641   28980  12.7805170314276
196646  196641   34591  12.8994111000000

我尝试获取每个组的最小值并使用以下代码显示,

df.columns = ['a','b','c']
df.index = df.a.astype(str)
dd=df.groupby('a').min()['c']

它给出了结果

196512    12.7805170314276
196795    12.7805170314276
196341    12.7805170314276
196346    12.7805170314276

但分组后,我想获得具有最小“c”值的行,按“a”列分组,并在结果中显示完整匹配的行,例如,

196512    118910      12.8983353775637  
196795     28978      12.7805170314276
196341     28972      12.7805170314276
196346     28980      12.7805170314276
3个回答

如果这可以帮助其他人。这是一个计算效率更高的解决方案。

TL;DR 版本

如果每一行已经有一个唯一的索引,那么这样做:

>>> df.loc[df.groupby('A')['C'].idxmin()]

如果您已经被“​​A”索引,那么首先将“A”转换回一列。

>>> df2 = df.reset_index()
>>> df2.loc[df2.groupby('A')['C'].idxmin()]

分步说明:

步骤1。

首先,确保数据框中的每一行都是唯一索引的。这是导入 csv 数据时的默认设置。例如

    >>> df = pd.read_csv('questionData.csv'); df
        A       B       C
    0   196512  1325    12.901051
    1   196512  114569  12.926770
    2   196512  118910  12.898335
    3   196512  100688  12.950509
    4   196795  28978   12.780517
    5   196795  34591   12.899411
    6   196795  13078   12.913575
    7   196795  24173   12.876965
    8   196341  118910  12.898335
    9   196341  100688  12.950509
    10  196641  28972   12.780517
    11  196641  34591   12.899411
    12  196346  118910  12.898335
    13  196346  100688  12.950509
    14  196646  28980   12.780517
    15  196646  34591   12.899411

另外:如果您已经将“A”列转换为索引,那么您可以将索引重新转换为列(https://stackoverflow.com/questions/20461165/how-to-convert-pandas-index-in-a -dataframe-to-a-column ) 通过执行以下操作:df.reset_index()

第2步。

使用pandas.DataFrame.idxmin函数检索每个组的最小值的索引。

下面例子的语义是这样的:“按‘A’分组,然后只看每组的‘C’列,最后返回每组中最小‘C’对应的索引。

>>> indices = df.groupby('A')['C'].idxmin; indices
A
196341     8
196346    12
196512     2
196641    10
196646    14
196795     4
Name: C, dtype: int64

步骤 3。

最后,使用pandas.DataFrame.loc在原始数据帧中检索到的索引来获取原始数据帧的行,这些行对应于按“A”分组的每个组中“C”的最小值。

>>> df.loc[indices]
    A       B       C
8   196341  118910  12.898335
12  196346  118910  12.898335
2   196512  118910  12.898335
10  196641  28972   12.780517
14  196646  28980   12.780517
4   196795  28978   12.780517

注意: groupby('A') 操作返回按 A 排序的组。因此 'indices' 按 A 排序。如果我们想要原始顺序,我们只需要这样做

>>> df.loc[indices].sort_index()
    A       B       C
2   196512  118910  12.898335
4   196795  28978   12.780517
8   196341  118910  12.898335
10  196641  28972   12.780517
12  196346  118910  12.898335
14  196646  28980   12.780517

你可以这样做。但我怀疑效率。

>> 将熊猫导入为 pd
>> df = pd.DataFrame({'a':[1,1,3,3],'b':[4,5,6,3], 'c':[1,2,3,5] })
>> df
   美国广播公司
0 1 4 1
1 1 5 2
2 3 6 3
3 3 3 5
>> df[df['c'].isin(df.groupby('a').min()['c'].values)]
   美国广播公司
0 1 4 1
2 3 6 3

首先检查您的数据。您无法获得索引196341的值12.780517该值将用于索引196641

现在,要在结果中获取“b”列,请使用pd.merge不要将列“a”作为索引。保持原状。

>>> df = pd.DataFrame({'a':[196512, 196512, 196512, 196512, 196795, 196795, 196795, 196795, 196341, 196341, 196641, 196641, 196346, 196346, 196646, 196646],'b':[1325 , 114569 , 118910 , 100688 , 28978 ,34591 , 13078 ,  24173 , 118910 , 100688 , 28972 , 34591 , 118910 , 100688 , 28980 , 34591 ],'c':[12.9010511000000 ,12.9267705000000 ,12.8983353775637 ,12.9505091000000 ,12.7805170314276 ,12.8994111000000 ,12.9135746000000 ,12.8769653100000 ,12.8983353775637 ,12.9505091000000 ,12.7805170314276 ,12.8994111000000 ,12.8983353775637 ,12.9505091000000 ,12.7805170314276 ,12.8994111000000 ]})
>>> df1 = df.groupby(['a'])['c'].min()
>>> df1
a
196341    12.898335
196346    12.898335
196512    12.898335
196641    12.780517
196646    12.780517
196795    12.780517
Name: c, dtype: float64

df1 在这里是一个系列类型的对象。将其转换为数据框。

>>> df1 = pd.DataFrame(df1, columns = ['c'])

此外,将 df1 的索引设为“a”列并更改索引。

>>> df1['a'] = df1.index
>>> df1.index = range(df1.shape[0])
>>> df1
       c       a
0  12.898335  196341
1  12.898335  196346
2  12.898335  196512
3  12.780517  196641
4  12.780517  196646
5  12.780517  196795

现在,您必须在'a''c'两列上将df1df连接起来。

>>> pd.merge(df,df1, on = ['a','c'])
    a       b          c
0  196512  118910  12.898335
1  196795   28978  12.780517
2  196341  118910  12.898335
3  196641   28972  12.780517
4  196346  118910  12.898335
5  196646   28980  12.780517 

你有你想要的输出!