python - pandas:按出现顺序排序

标签 python pandas sorting

假设我们有一个数据框:

df = pd.DataFrame(pd.np.zeros((15,10,)), dtype=int, \
    index=[['a']*5+['b']*5+['c']*5, list(range(15))])
df.index.names=['index0', 'index1']
pd.np.random.seed(0)
for i, v in df.iterrows():
    v.loc[pd.np.random.randint(10)] = 1

df

               0  1  2  3  4  5  6  7  8  9
index0 index1                              
a      0       0  0  0  0  0  1  0  0  0  0
       1       1  0  0  0  0  0  0  0  0  0
       2       0  0  0  1  0  0  0  0  0  0
       3       0  0  0  1  0  0  0  0  0  0
       4       0  0  0  0  0  0  0  1  0  0
b      5       0  0  0  0  0  0  0  0  0  1
       6       0  0  0  1  0  0  0  0  0  0
       7       0  0  0  0  0  1  0  0  0  0
       8       0  0  1  0  0  0  0  0  0  0
       9       0  0  0  0  1  0  0  0  0  0
c      10      0  0  0  0  0  0  0  1  0  0
       11      0  0  0  0  0  0  1  0  0  0
       12      0  0  0  0  0  0  0  0  1  0
       13      0  0  0  0  0  0  0  0  1  0
       14      0  1  0  0  0  0  0  0  0  0

如何先按“1”的出现顺序对 block a、b和c中的行进行排序,然后再对a、b和c进行排序?

预期输出:

               0  1  2  3  4  5  6  7  8  9
index0 index1                              
a      1       1  0  0  0  0  0  0  0  0  0
       2       0  0  0  1  0  0  0  0  0  0
       3       0  0  0  1  0  0  0  0  0  0
       0       0  0  0  0  0  1  0  0  0  0
       4       0  0  0  0  0  0  0  1  0  0
c      14      0  1  0  0  0  0  0  0  0  0
       11      0  0  0  0  0  0  1  0  0  0
       10      0  0  0  0  0  0  0  1  0  0
       12      0  0  0  0  0  0  0  0  1  0
       13      0  0  0  0  0  0  0  0  1  0
b      8       0  0  1  0  0  0  0  0  0  0
       6       0  0  0  1  0  0  0  0  0  0
       9       0  0  0  0  1  0  0  0  0  0
       7       0  0  0  0  0  1  0  0  0  0
       5       0  0  0  0  0  0  0  0  0  1

编辑:这些值可以不是“1”,实际上这些是不同的文本值。

最佳答案

一种方法是将 pandas.DataFrame.groupbyidxmaxsort_values 结合使用:

import pandas as pd

l = (d.loc[d.idxmax(1).sort_values().index] for _, d in df.groupby('index0'))
new_df = pd.concat(sorted(l, key= lambda x:list(x.sum()), reverse=True))
print(new_df)

输出:

               0  1  2  3  4  5  6  7  8  9
index0 index1                              
a      1       1  0  0  0  0  0  0  0  0  0
       2       0  0  0  1  0  0  0  0  0  0
       3       0  0  0  1  0  0  0  0  0  0
       0       0  0  0  0  0  1  0  0  0  0
       4       0  0  0  0  0  0  0  1  0  0
c      14      0  1  0  0  0  0  0  0  0  0
       11      0  0  0  0  0  0  1  0  0  0
       10      0  0  0  0  0  0  0  1  0  0
       12      0  0  0  0  0  0  0  0  1  0
       13      0  0  0  0  0  0  0  0  1  0
b      8       0  0  1  0  0  0  0  0  0  0
       6       0  0  0  1  0  0  0  0  0  0
       9       0  0  0  0  1  0  0  0  0  0
       7       0  0  0  0  0  1  0  0  0  0
       5       0  0  0  0  0  0  0  0  0  1

如果1是文本并且其余部分相同,请尝试使用pandas.Dataframe.ne

tmp = df.ne(0)
# same operation
new_df = df.loc[new_tmp.index]

关于python - pandas:按出现顺序排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57454428/

相关文章:

algorithm - 在 O(n) 中查找 2^k 个最大元素

python - 连接具有不同第一维的二维数组

c# - 在 Python 中将字符串从 sha1 哈希转换为 base 64

python - NumPy 排序函数返回 None

python - 编写这个 for 循环的更有效方法?

python - 性能:Pandas index.intersection() 与集合交集

python - Pandas 数据框掩码将值写入新列

python - 使用 Python Turtle 生成重叠三角形

c++ - 如何使用分区解决重复的top-k问题?

jsf - PrimeFaces 数据表排序不起作用