pandas数据框架按分组排序,按绝对值排序分组

3

大家好,我希望找到一种高效的方法来按绝对值对分组数据进行排序。

例如:

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

以下是数据框和分组参考:

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))

我的IT技术工作通常都很顺利,但有时会出现错误。

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

尽管我在提供的数据集中没有遇到过这个错误,但是我在使用大型和不同的数据集时(我无法提供这些数据集),有些数据集中会出现这个错误,但是我确定数据与此无关,因为它们都非常相似。

我已经做了一些调试,每次出现这个错误都是当apply处理第一组时。

那么有没有更好的方法可以在不使用apply的情况下解决呢?

注意:我尝试了transform,但它会丢弃分组并输出一个不同的数据集,这绝对不是我想要的,我想保留分组和格式。也许我使用它的方式不正确?

2个回答

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
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

很棒的Pythonic答案! - Luis Miguel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接