【问题标题】:Unexpected result of DataFrame sortDataFrame排序的意外结果
【发布时间】:2013-04-05 06:09:00
【问题描述】:

当我使用几列 (['Symbol','Year','Month','Day']) 对我的 DataFrame 进行排序时,生成的 DataFrame 按Symbol > Year > Month 排序,但不是Day 排序:

In [1]: df = pd.DataFrame({'Symbol': {79: 'F', 81: 'F', 82: 'F', 83: 'F', 84: 'F', 85: 'F', 86: 'F', 87: 'F', 89: 'F'}, 'Shares': {79: 100, 81: 100, 82: 100, 83: 100, 84: 100, 85: 100, 86: 100, 87: 100, 89: 100}, 'Month': {79: '08', 81: '08', 82: '08', 83: '08', 84: '08', 85: '08', 86: '08', 87: '08', 89: '09'}, 'Year': {79: '2008', 81: '2008', 82: '2008', 83: '2008', 84: '2008', 85: '2008', 86: '2008', 87: '2008', 89: '2008'}, 'Action': {79: 'Sell', 81: 'Sell', 82: 'Buy', 83: 'Sell', 84: 'Buy', 85: 'Sell', 86: 'Buy', 87: 'Sell', 89: 'Sell'}, 'Day': {79: 2L, 81: 4L, 82: '06', 83: 11L, 84: '13', 85: 18L, 86: '18', 87: 23L, 89: 22L}})

In [2]: df
Out[2]:
   Action Day Month  Shares Symbol  Year
79   Sell   2    08     100      F  2008
81   Sell   4    08     100      F  2008
82    Buy  06    08     100      F  2008
83   Sell  11    08     100      F  2008
84    Buy  13    08     100      F  2008
85   Sell  18    08     100      F  2008
86    Buy  18    08     100      F  2008
87   Sell  23    08     100      F  2008
89   Sell  22    09     100      F  2008

In [3]: df.sort(['Symbol','Year','Month','Day'])
Out[3]:
   Action Day Month  Shares Symbol  Year
79   Sell   2    08     100      F  2008
81   Sell   4    08     100      F  2008
83   Sell  11    08     100      F  2008
85   Sell  18    08     100      F  2008
87   Sell  23    08     100      F  2008
82    Buy  06    08     100      F  2008
84    Buy  13    08     100      F  2008
86    Buy  18    08     100      F  2008
89   Sell  22    09     100      F  2008

为什么sort 没有按预期工作?

【问题讨论】:

  • 您能否编辑您的帖子以包含您拥有的最小复制案例(并提及您使用的是哪个版本的熊猫)?
  • 相应编辑。谢谢。
  • 看起来您使用的名称与列标题中的名称不同
  • @zach 会抛出 KeyError... :s
  • 那些前导零是怎么回事 (06/08)?您的数据类型似乎有些奇怪。 print df_orders.dtypes 给了什么?你能编辑你的帖子以包含df_orders.to_dict()吗?

标签: sorting dataframe pandas


【解决方案1】:

它没有像你期望的那样工作,因为 Days 被存储为混合类型(字符串和长整数),并且由于 字符串在 python 中“大于”数字(排序看起来像是出乎意料的) .

您可以通过apply-ing int将此列转换为整数:

df['Day'] = df['Day'].apply(int)

我也会考虑在月份和年份中执行此操作,因为在您的 DataFrame 中这些是字符串(也许作为 int 更有意义):

df['Mo.'] = df['Mo.'].apply(int)
df['Year'] = df['Year'].apply(int)

那你可以sort按天:

In [11]: df.sort(['Day'])
Out[11]:
   Indx  Year  Mo.  Day Sym Action  Shares
0    79  2008    8    2   F   Sell     100
1    81  2008    8    4   F   Sell     100
5    82  2008    8    6   F    Buy     100
2    83  2008    8   11   F   Sell     100
6    84  2008    8   13   F    Buy     100
3    85  2008    8   18   F   Sell     100
7    86  2008    8   18   F    Buy     100
8    89  2008    9   22   F   Sell     100
4    87  2008    8   23   F   Sell     100

或者用多列排序:

In [12]: df.sort(['Mo.', 'Day'])
Out[12]:
   Indx  Year  Mo.  Day Sym Action  Shares
0    79  2008    8    2   F   Sell     100
1    81  2008    8    4   F   Sell     100
5    82  2008    8    6   F    Buy     100
2    83  2008    8   11   F   Sell     100
6    84  2008    8   13   F    Buy     100
3    85  2008    8   18   F   Sell     100
7    86  2008    8   18   F    Buy     100
4    87  2008    8   23   F   Sell     100
8    89  2008    9   22   F   Sell     100

In [13]: df.sort(['Day', 'Mo.'])
Out[13]:
   Indx  Year  Mo.  Day Sym Action  Shares
0    79  2008    8    2   F   Sell     100
1    81  2008    8    4   F   Sell     100
5    82  2008    8    6   F    Buy     100
2    83  2008    8   11   F   Sell     100
6    84  2008    8   13   F    Buy     100
3    85  2008    8   18   F   Sell     100
7    86  2008    8   18   F    Buy     100
8    89  2008    9   22   F   Sell     100
4    87  2008    8   23   F   Sell     100

加上ascending 参数:

In [14]: df.sort(['Mo.', 'Day'], ascending=[True, False])
Out[14]:
   Indx  Year  Mo.  Day Sym Action  Shares
4    87  2008    8   23   F   Sell     100
3    85  2008    8   18   F   Sell     100
7    86  2008    8   18   F    Buy     100
6    84  2008    8   13   F    Buy     100
2    83  2008    8   11   F   Sell     100
5    82  2008    8    6   F    Buy     100
1    81  2008    8    4   F   Sell     100
0    79  2008    8    2   F   Sell     100
8    89  2008    9   22   F   Sell     100

... 将按预期工作。

【讨论】:

  • 当我尝试该代码时,我最终得到与您相同的输出,除了“Sell”是第一个。
  • @ErikGibbons 很有趣...正如 DSM 所暗示的那样,我认为您读取数据的方式有些可疑(您是否使用了 read_csv)? df.dtypes 和/或 df.to_dict() 的输出可能会有所帮助:)
  • @AndyHayden:既然我们已经看到了.to_dict(),你愿意接受吗?
  • 这与“Day”在 [x]L 和只是 'x' 之间分裂的事实有关吗?这意味着什么?
  • @ErikGibbons 您可以使用df['Day'] = df['Day'].apply(int) 修复您的DatFrame,同样使用'Mo.''Year' :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-10
  • 2021-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-15
相关资源
最近更新 更多