在数据框的列中对列表的值进行排序

时间:2017-12-29 12:03:33

标签: python pandas dataframe

我的数据框为df

   info      task                                               timestamp  
0  foo       ABC                                           ['2016-04-30']  
1  bar       DEF ['2016-01-31', '2015-06-30', '2016-06-30', '2016-08-31']  
2  bar       GHI               ['2015-12-31', '2016-08-31', '2016-05-31']  
3  foo       JKL                                           ['2017-03-31']  
4  foo       XYZ               ['2016-02-29', '2015-10-31', '2016-01-31']  

我想对 timestamp 列中的日期进行排序。请注意,timestamp列中的值位于列表和字符串类型中。

期望的输出:

   info      task                                               timestamp  
0  foo       ABC                                           ['2016-04-30']  
1  bar       DEF ['2015-06-30', '2016-01-31', '2016-06-30', '2016-08-31']  
2  bar       GHI               ['2015-12-31', '2016-05-31', '2016-08-31']  
3  foo       JKL                                           ['2017-03-31']  
4  foo       XYZ               ['2015-10-31', '2016-01-31', '2016-02-29'] 

2 个答案:

答案 0 :(得分:1)

所以,显而易见的答案是在这里拨打apply(sorted),但我会继续进行切线,因为这是数据结构的一个根本缺陷。

让我们先把你的数据弄平。

df

  info task                                         timestamp
0  foo  ABC                                      [2016-04-30]
1  bar  DEF  [2016-01-31, 2015-06-30, 2016-06-30, 2016-08-31]
2  bar  GHI              [2015-12-31, 2016-08-31, 2016-05-31]
3  foo  JKL                                      [2017-03-31]
4  foo  XYZ              [2016-02-29, 2015-10-31, 2016-01-31]
v = df.values
i = v[:, :-1].repeat(df.timestamp.str.len(), axis=0)
j = np.concatenate(v[:, -1]).reshape(-1, 1)

df = pd.DataFrame(np.hstack((i, j)), columns=df.columns)

   info task   timestamp
0   foo  ABC  2016-04-30
1   bar  DEF  2016-01-31
2   bar  DEF  2015-06-30
3   bar  DEF  2016-06-30
4   bar  DEF  2016-08-31
5   bar  GHI  2015-12-31
6   bar  GHI  2016-08-31
7   bar  GHI  2016-05-31
8   foo  JKL  2017-03-31
9   foo  XYZ  2016-02-29
10  foo  XYZ  2015-10-31
11  foo  XYZ  2016-01-31

现在,groupby前两列并致电sort_values -

df.groupby(['info', 'task'], sort=False)\
  .timestamp\
  .apply(pd.Series.sort_values)\
  .reset_index(level=[0, 1])

   info task   timestamp
0   foo  ABC  2016-04-30
2   bar  DEF  2015-06-30
1   bar  DEF  2016-01-31
3   bar  DEF  2016-06-30
4   bar  DEF  2016-08-31
5   bar  GHI  2015-12-31
7   bar  GHI  2016-05-31
6   bar  GHI  2016-08-31
8   foo  JKL  2017-03-31
10  foo  XYZ  2015-10-31
11  foo  XYZ  2016-01-31
9   foo  XYZ  2016-02-29

仍然需要申请,但我愿意下注的速度要快得多,特别是考虑到您的其他操作可能不再需要apply

答案 1 :(得分:0)

Apply允许您调用Series:

值的函数
df.timestamp.apply(sorted)

然后,您可以将结果分配回时间戳列。