pandas Dataframe groupby,按绝对值对组进行排序

时间:2015-11-21 21:03:07

标签: python numpy pandas dataframe

大家好我基本上想找到一种有效的方法来按绝对值对分组数据进行排序。

例如:

item       itemID value
cars         A     5
             B    -3
             C     2
             D    -4
             E     1
houses       A    -2
             B     4
             C    -6
             D     3
             E     7

应该是:

item        itemID value
 car          A      5
              D     -4             
              B     -3
              C      2
              E      1
houses        E      7
              C     -6
              B      4
              D      3
              A     -2

以下是dataframe和groupby供参考:

data = {'item':['car','car','car','car','car','houses','houses','houses','houses','houses'], 'itemID':['A','B','C','D','E','A','B','C','D','E'],'value':[5,-3,2,-4,1,-2,4,-6,3,7]}
df = pd.DataFrame(data)
gdf = df.groupby('item')

我试过这个:

gdf.apply(lambda g: g.reindex(g[['value']].abs().sort('value', ascending=True).index))

并且大部分时间都可以正常工作,但有时它会给我错误

ValueError: Shape of passed values is (100,10), indices imply (105, 10)

我在提供的数据集中确实没有出现此错误,但我在大型不同的数据集中使用它,我无法在此处提供并在其中一些数据集中使用它但我确定数据与它无关,因为它们都非常相似。

我已完成一些调试,每当我收到此错误时,应用重复第一组。

那么有没有更好的方法可以不使用申请?

注意:我尝试过转换,但它摆脱了组并输出了一个不同的数据集,这绝对不是我想要的,我想保留组和格式。也许我使用它错了?

2 个答案:

答案 0 :(得分:1)

考虑简单地通过定义的函数创建绝对值列,在groupby上应用函数,然后对项目升序和绝对值降序进行排序。最后,过滤掉新创建的不需要的列:

# CREATE ABS VALUE FUNCTION TO CREATE COLUMN
def valsort(row):    
    row['absvalue'] = row['value'].abs()
    return row

# APPLY FUNCTION AND RESET DATA FRAME
gdf = df.groupby(['item', 'itemID']).apply(valsort).sort(['item', 'absvalue'], 
                                                    ascending=[1,0]).reset_index()

# FILTER OUT ABS VALUE
gdf = gdf[['item', 'itemID', 'value']]

print(gdf)

<强>输出

     item itemID  value
0     car      A      5
1     car      D     -4
2     car      B     -3
3     car      C      2
4     car      E      1
5  houses      E      7
6  houses      C     -6
7  houses      B      4
8  houses      D      3
9  houses      A     -2

答案 1 :(得分:1)

In [48]:
df['value'] = df.groupby(df.index)['value'].apply(lambda x : x[np.argsort(np.abs(x))][::-1])
df
Out[48]:
     itemID value
item        
cars    A   5
cars    B   -4
cars    C   -3
cars    D   2
cars    E   1
houses  A   7
houses  B   -6
houses  C   4
houses  D   3
houses  E   -2