pandas DataFrame按重复排序行

时间:2016-08-15 04:06:36

标签: python sorting pandas dataframe duplicates

如何对DataFrame进行排序,以便重复列中的行被回收"。

例如,我原来的DataFrame看起来像这样:

In [3]: df
Out[3]: 
    A  B
0  r1  0
1  r1  1
2  r2  2
3  r2  3
4  r3  4
5  r3  5

我希望转向:

In [3]: df_sorted
Out[3]: 
    A  B
0  r1  0
2  r2  2
4  r3  4
1  r1  1
3  r2  3
5  r3  5

行进行排序,以使列A中的行处于"再循环"方式。

我在Pandas中搜索过API,但似乎没有任何正确的方法可以做到这一点。我可以编写一个复杂的函数来完成这个,但只是想知道是否有任何智能方法或现有的pandas方法可以做到这一点?非常感谢。

更新: 为错误的陈述道歉。在我的真正问题中,列B包含字符串值。

1 个答案:

答案 0 :(得分:4)

您可以使用cumcount来计算A列中的重复项,然后使用A sort_values(不需要样本,实际数据可能很重要)然后按C。上次按drop删除了列C

df['C'] = df.groupby('A')['A'].cumcount()
df.sort_values(by=['C', 'A'], inplace=True)
print (df)
    A  B  C
0  r1  0  0
2  r2  2  0
4  r3  4  0
1  r1  1  1
3  r2  3  1
5  r3  5  1

df.drop('C', axis=1, inplace=True)
print (df)
    A  B
0  r1  0
2  r2  2
4  r3  4
1  r1  1
3  r2  3
5  r3  5

<强>计时

小df(len(df)=6

In [26]: %timeit (jez(df))
1000 loops, best of 3: 2 ms per loop

In [27]: %timeit (boud(df1))
100 loops, best of 3: 2.52 ms per loop

大df(len(df)=6000

In [23]: %timeit (jez(df))
100 loops, best of 3: 3.44 ms per loop

In [28]: %timeit (boud(df1))
100 loops, best of 3: 2.52 ms per loop

计时代码:

df = pd.concat([df]*1000).reset_index(drop=True) 
df1 = df.copy()

def jez(df):
    df['C'] = df.groupby('A')['A'].cumcount()
    df.sort_values(by=['C', 'A'], inplace=True)
    df.drop('C', axis=1, inplace=True)
    return (df)

def boud(df):
    df['C'] = df.groupby('A')['B'].rank()
    df = df.sort_values(['C', 'A'])
    df.drop('C', axis=1, inplace=True)
    return (df)
100 loops, best of 3: 4.29 ms per loop