分组由pandas dataframe列的相同部分字符串组成

时间:2016-02-07 22:13:12

标签: python csv pandas ipython dataframe

我有几个csv文件,每个文件在一个月内包含一个股票价格,并且有数百万个数据。 原始csv数据数据如下:

AA_Candy.csv

Index   CompanyName      Time       Price
  1      AA Candy    030101090355   1.78
  2      AA Candy    030101091533   1.79
  .......
333498   AA Candy    031231145556   2.18

BB_Cookie.csv

   1     BB Cookie   030101090225   3.20
   2     BB Cookie   030101090845   3.14
  .......
391373   BB Cookie   031231145958   3.88

我使用python和pandas处理数据,在加载并组合一些数据文件后,现在我有一个数据框,如:

框:

Index   CompanyName      Time       Price
  1      AA Candy    030101090355   1.78
  2      AA Candy    030101091533   1.79
  .......
333498   AA Candy    031231145556   2.18
333499   BB Cookie   030101090225   3.20
333500   BB Cookie   030101090845   3.14
  .......
712871   BB Cookie   031231145958   3.88

时间031231145958代表2013-12-31 14:59:58

现在我想获得每家公司每一小时的最高价格和最终价格,并获得如下输出文件:

range_start   AA Candy/Max    AA Candy/Close    BB Cookie/Max     BB Cookie/Close
0301010900     1.79              1.77            3.20              3.10
........
0312311400     2.24              2.18            3.88              3.88

因此我希望将CompanyName和Time的前8个字符组合在一起获得同一公司的数据,然后进行计算以找出每个公司的最大价格值和最终价格值并输出相同的结果一小时开始;让companyName / Max或Close为新列名。

因为我是熊猫和数据框架的新手,所以我有以下问题:

  1. 如何按时间列(对象)的前8个字符对数据进行分组,然后获得我的预期值?
  2. 如何将新的输出数据框/矩阵形成为我的预期输出?
  3. 谢谢!

2 个答案:

答案 0 :(得分:3)

对公司名称和字符串时间戳的前8个字符(即日期加小时)执行groupby。然后在价格上使用agg来获取每个(第一个,最大值,最小值和最后一个)的自定义函数。取消堆叠公司名称,交换公司名称的级别,打开/高/低/关闭,并可选择对符号进行排序。

gb = (df.groupby(['CompanyName', df.Time.str[:8]])
        .Price
        .agg({'open': 'first', 
              'high': np.max, 
              'low': np.min, 
              'close': 'last'})[['open', 'high', 'low', 'close']]
        .unstack('CompanyName'))
gb.columns = gb.columns.swaplevel(0, 1)
>>> gb.sortlevel(level=0, axis=1)
CompanyName AA Candy                   BB Cookie                  
                open  high   low close      open  high   low close
Time                                                              
03010109        1.78  1.79  1.78  1.79      3.20  3.20  3.14  3.14
03123114        2.18  2.18  2.18  2.18      3.88  3.88  3.88  3.88

答案 1 :(得分:0)

关于第一个问题,您可以使用

df.groupby(df.Time.str[0:8])

对于您的第二个问题,unstack应该是您想要的:

df.groupby(df.Time.str[0:8]).unstack()