根据组属性切片Pandas DataFrame

时间:2017-09-17 17:17:12

标签: python pandas dataframe

我有一个Pandas DataFrame,比方说有两列,GroupR(这里是负数)。例如:

df = pd.DataFrame({'Group':np.random.randint(0, 5, 20), 
                   'R'    :np.random.rand(20) * -10.0})

我想在每个组中创建一个新的DataFrame(对于具有相同Group的行),只有最小的R和低于最小{{1的行}} + 3。

例如,如果R看起来像(我按df排序,然后按Group排序)

R

该功能应该返回

Group    R  
1       -10.1
1       -12.3
1       -15.5
2       -8.7
2       -9.0
2       -11.4
2       -11.5
2       -13.1
2       -15.9

你是怎么做到的?

3 个答案:

答案 0 :(得分:1)

使用groupby

df['Max']=df.groupby('Group')['R'].transform('max')
df[(df['Max']-df['R'])<3].drop('Max',1)

Out[105]: 
   Group     R
0      1 -10.1
1      1 -12.3
3      2  -8.7
4      2  -9.0
5      2 -11.4
6      2 -11.5

一线解决方案:

df[(df.groupby('Group')['R'].transform('max')-df['R'])<3]

答案 1 :(得分:1)

我首先要按照&#39; Group&#39;并返回一个布尔值,表示组中的每个值是否小于R,然后使用此值来过滤原始数据框

keep = df.groupby('Group')['R'].apply(lambda x: x < x.min() + 3)
keep
0     True
1     True
2    False
3     True
4     True
5     True
6     True
7    False
8    False
....

df[keep].sort_values(['Group', 'R'], ascending=[True, False])

   Group     R
0      1 -10.1
1      1 -12.3
3      2  -8.7
4      2  -9.0
5      2 -11.4
6      2 -11.5

答案 2 :(得分:1)

首先排序,然后通过boolen mask选择:

df = df.sort_values(['Group', 'R'], ascending=[True, False])
df = df[df.groupby('Group')['R'].apply(lambda x: x > x.iat[0] - 3)]
print (df)
   Group     R
0      1 -10.1
1      1 -12.3
3      2  -8.7
4      2  -9.0
5      2 -11.4
6      2 -11.5

类似的解决方案:

df = df.groupby('Group')['R'].apply(lambda x: x[x > x.iat[0] - 3]).reset_index(level=0)
print (df)

   Group     R
0      1 -10.1
1      1 -12.3
3      2  -8.7
4      2  -9.0
5      2 -11.4
6      2 -11.5