按因子分组并返回其他列的第二个最低值

2024-09-28 23:22:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我想按zipcode列中的值对这个数据帧进行分组,然后在另一个(称为rate)列中返回second lowestrate或lowestrate或maxrate。你知道吗

例如,从这个df:

zipcode state   county_code name    rate_area_x plan_id metal_level rate    rate_area_y
36749   AL  1001    Autauga 11  52161YL6358432  Silver  245.82  6
36749   AL  1001    Autauga 11  01100AO4222848  Silver  271.77  5
36749   AL  1001    Autauga 11  24848KC5063721  Silver  264.84  1
36749   AL  1001    Autauga 11  89885YK0256118  Silver  269.11  8
36749   AL  1001    Autauga 11  65392ON5819785  Silver  305.02  12
30165   AL  1019    Cherokee    13  52161YL6358432  Silver  245.82  6
30165   AL  1019    Cherokee    13  01100AO4222848  Silver  271.77  5
30165   AL  1019    Cherokee    13  24848KC5063721  Silver  264.84  1
30165   AL  1019    Cherokee    13  89885YK0256118  Silver  269.11  8
30165   AL  1019    Cherokee    13  65392ON5819785  Silver  305.02  12
30165   AL  1019    Cherokee    13  90884WN5801293  Silver  323.25  2
30165   AL  1019    Cherokee    13  79113BU1788705  Silver  344.81  7

我希望:

zipcode rate
36749   245.82
30165   245.82

在R中,我这样做是为了得到每个zipcode组的最小值:

grouped_df <- df %>%
              group_by(zipcode) %>%
              summarise(rate = min(rate))

但是如何使用Python的Pandas获得第二低的速率值呢?


Tags: 数据dfsilverratecodeareastateal
3条回答

编辑:我给你两个最小的和第二个最小的,供你在一般情况下使用。然而,正如@WenYoBen在评论中提到的,你可能只想要第二低的。如果是这样的话,您只需要链接reset_indexdropdrop_duplicates就可以得到最小值或第二小值,如下所示:

获取最小值

df.groupby('zipcode').rate.nsmallest(2).reset_index().drop('level_1',1) \
  .drop_duplicates(subset=['zipcode'])

Out[2108]:
       zipcode    rate
    0    30165  245.82
    2    36749  245.82

获得第二个最小值

df.groupby('zipcode').rate.nsmallest(2).reset_index().drop('level_1',1) \
  .drop_duplicates(subset=['zipcode'], keep='last')

Out[2109]:
   zipcode    rate
1    30165  264.84
3    36749  264.84    

原件

groupby.nsmallest将给出每组中最小的和第二小的

df.groupby('zipcode').rate.nsmallest(2)

Out[2083]:
zipcode
30165    5    245.82
         7    264.84
36749    0    245.82
         2    264.84
Name: rate, dtype: float64

要将结果放入Dataframe,可以使用group_by方法和to_frame。注意,要获得第n个最低值(而不是[:n]个最低值),请对df排序并选择所需的n。你知道吗

import pandas as pd

data="""zipcode state   county_code name    rate_area_x plan_id metal_level rate    rate_area_y
36749   AL  1001    Autauga 11  52161YL6358432  Silver  245.82  6
36749   AL  1001    Autauga 11  01100AO4222848  Silver  271.77  5
36749   AL  1001    Autauga 11  24848KC5063721  Silver  264.84  1
36749   AL  1001    Autauga 11  89885YK0256118  Silver  269.11  8
36749   AL  1001    Autauga 11  65392ON5819785  Silver  305.02  12
30165   AL  1019    Cherokee    13  52161YL6358432  Silver  245.82  6
30165   AL  1019    Cherokee    13  01100AO4222848  Silver  271.77  5
30165   AL  1019    Cherokee    13  24848KC5063721  Silver  264.84  1
30165   AL  1019    Cherokee    13  89885YK0256118  Silver  269.11  8
30165   AL  1019    Cherokee    13  65392ON5819785  Silver  305.02  12
30165   AL  1019    Cherokee    13  90884WN5801293  Silver  323.25  2
30165   AL  1019    Cherokee    13  79113BU1788705  Silver  344.81  7"""

# create dataframe
n_columns = 9
data = [data.split()[x:x+n_columns] for x in range(0, len(data.split()), n_columns)]
df = pd.DataFrame(data[1:], columns=data[0]).apply(pd.to_numeric, errors='ignore')

# ensure the dataframe is sorted
df = df.sort_values(['zipcode','rate'])

min_df = df.groupby('zipcode').rate.min().to_frame(name = 'rate').reset_index()

max_df = df.groupby('zipcode').rate.max().to_frame(name = 'rate').reset_index()

second_lowest_df = df.groupby('zipcode').rate.nth(1).to_frame(name = 'rate').reset_index()

sort然后groupby+nth。这使您可以灵活地选择任意排列的值(通过传递列表)。如果不想重复计算同一个值,请删除重复项。你知道吗

df.sort_values(['rate']).groupby('zipcode').rate.nth([1])
#zipcode
#30165    264.84
#36749    264.84
#Name: rate, dtype: float64

如果需要最小值、第四小值和最大值:

df.sort_values(['rate']).groupby('zipcode').rate.nth([0, 3, -1])
#zipcode
#30165    245.82
#30165    271.77
#30165    344.81
#36749    245.82
#36749    271.77
#36749    305.02
#Name: rate, dtype: float64

超出范围的选择在不存在的组中被忽略:

df.sort_values(['rate']).groupby('zipcode').rate.nth(5)
#zipcode
#30165    323.25
#Name: rate, dtype: float64

冗余选择器不重复计数(6和-1都指30165中的max元素)

df.sort_values(['rate']).groupby('zipcode').rate.nth([6, 6, -1])
#zipcode
#30165    344.81
#36749    305.02
#Name: rate, dtype: float64

相关问题 更多 >