在 pandas DataFrame 中按列名对数据进行排序

3

你好,我在处理pandas DataFrame中的一些数据排序问题。这些数据的格式与我所熟悉的不同,我不知道该如何解决。需要排序的数据格式如下:

[['2016-05-23', 'name1', 'data1'],
['2016-05-23', 'name2', 'data2'],
['2016-05-24', 'name1', 'data1'],
['2016-05-24', 'name2', 'data2'],
['2016-05-25', 'name1', 'data1'],
['2016-05-25', 'name2', 'data2'],
['2016-05-26', 'name1', 'data1'],
['2016-05-26', 'name2', 'data2'],
['2016-05-27', 'name1', 'data1'],
['2016-05-27', 'name2', 'data2']]

我想要做的是按日期排序,并以名称作为列名。

[['2016-05-23, 'data1', 'data2'],
['2016-05-24', 'data1', 'data2'],
['2016-05-25', 'data1', 'data2'] and so on...]

有没有一些特定的pandas命令可以实现这个功能?我希望这个解决方案不仅仅适用于两个名称列,而且更加通俗易懂。我不知道如何做到这一点,如果有人能帮助我,我将不胜感激。

1个回答

2
我认为你需要pivot
import pandas as pd

df = pd.DataFrame([['2016-05-23', 'name1', 'data1'],
['2016-05-23', 'name2', 'data2'],
['2016-05-24', 'name1', 'data1'],
['2016-05-24', 'name2', 'data2'],
['2016-05-25', 'name1', 'data1'],
['2016-05-25', 'name2', 'data2'],
['2016-05-26', 'name1', 'data1'],
['2016-05-26', 'name2', 'data2'],
['2016-05-27', 'name1', 'data1'],
['2016-05-27', 'name2', 'data2']], columns = ['a','b','c'])

print (df)
            a      b      c
0  2016-05-23  name1  data1
1  2016-05-23  name2  data2
2  2016-05-24  name1  data1
3  2016-05-24  name2  data2
4  2016-05-25  name1  data1
5  2016-05-25  name2  data2
6  2016-05-26  name1  data1
7  2016-05-26  name2  data2
8  2016-05-27  name1  data1
9  2016-05-27  name2  data2

#convert column a to datetime
df['a'] = pd.to_datetime(df.a)

print (df.pivot(index='a', columns='b', values='c'))
b           name1  name2
a                       
2016-05-23  data1  data2
2016-05-24  data1  data2
2016-05-25  data1  data2
2016-05-26  data1  data2
2016-05-27  data1  data2

然后,如果您需要使用sort_values,例如按列name1排序:
import pandas as pd

df = pd.DataFrame([['2016-05-23', 'name1', 9],
['2016-05-23', 'name2', 4],
['2016-05-24', 'name1', 5],
['2016-05-24', 'name2', 1],
['2016-05-25', 'name1', 5],
['2016-05-25', 'name2', 7],
['2016-05-26', 'name1', 10],
['2016-05-26', 'name2', 7],
['2016-05-27', 'name1', 0],
['2016-05-27', 'name2', 1]], columns = ['a','b','c'])
print (df)
            a      b   c
0  2016-05-23  name1   9
1  2016-05-23  name2   4
2  2016-05-24  name1   5
3  2016-05-24  name2   1
4  2016-05-25  name1   5
5  2016-05-25  name2   7
6  2016-05-26  name1  10
7  2016-05-26  name2   7
8  2016-05-27  name1   0
9  2016-05-27  name2   1

print (df.pivot(index='a', columns='b', values='c').sort_values('name1'))
b           name1  name2
a                       
2016-05-27      0      1
2016-05-24      5      1
2016-05-25      5      7
2016-05-23      9      4
2016-05-26     10      7

有时候 pivot 无法正常工作,那么就使用pivot_table
print (df.pivot_table(index='a', columns='b', values='c'))

但是,pivot_table 使用 aggfunc,默认为 aggfunc=np.mean 如果出现重复的话。更好的解释和示例在这里文档中。
最后,你可以使用reset_indexrename_axis(在pandas 0.18.0中新增):
print (df.pivot(index='a', columns='b', values='c')
         .reset_index()
         .rename_axis(None, axis=1))
            a  name1  name2
0  2016-05-23      9      4
1  2016-05-24      5      1
2  2016-05-25      5      7
3  2016-05-26     10      7
4  2016-05-27      0      1

#pandas bellow 0.18.0
df1 = df.pivot(index='a', columns='b', values='c').reset_index()
df1.columns.name = None
print (df1)
            a  name1  name2
0  2016-05-23      9      4
1  2016-05-24      5      1
2  2016-05-25      5      7
3  2016-05-26     10      7
4  2016-05-27      0      1

谢谢,这似乎有效,有没有办法将它们合并成一个新的数据框?我试过在一个新的DataFrame中执行print(df.pivot(index = 'a',columns ='b',values ='c').sort_values('a')),以使它按日期排序,但那样做不起作用。 - Siesta
但是 a 是索引,而且已经排序了... 如果没有排序,您可以使用 df1 = df.pivot(index='a', columns='b', values='c').reset_index().sort_values('a') - jezrael
我还添加了将字符串列a转换为日期时间的代码,请参见编辑。 - jezrael
抱歉,是我写错了。看起来它现在运行得很完美。 - Siesta
感谢您的接受。很高兴能够帮助您!祝您好运! - jezrael

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