我想将此数据帧按zipcode
列中的值进行分组,然后在另一个(称为“速率”)列中返回second lowest
速率或lowest
速率或{ {1}}率。
例如,来自此df:
max
我希望:
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
在R中,我这样做是为了获取每个邮政编码组的最小值:
zipcode rate
36749 245.82
30165 245.82
但是如何使用Python的Pandas获得第二低的费率值?
答案 0 :(得分:4)
编辑:在一般情况下,我会为您提供最小和第二个最小的选择。但是,正如@WenYoBen在评论中提到的那样,您可能只希望倒数第二。在这种情况下,您只需要链接reset_index
,drop
和drop_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
答案 1 :(得分:1)
要将结果放入Dataframe
中,可以将group_by
方法与to_frame
一起使用。请注意,要获得第n个最低值(而不是第[:nth]个最低值),请对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()
答案 2 :(得分:1)
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中的最大元素)
df.sort_values(['rate']).groupby('zipcode').rate.nth([6, 6, -1])
#zipcode
#30165 344.81
#36749 305.02
#Name: rate, dtype: float64