Python3如何在Pandas Dataframe

时间:2017-03-28 21:03:03

标签: python pandas

我想从大型Pandas数据帧创建一个图。数据采用以下格式

Type     Number    ...unimportant additional columns

Foo       13  ...
Foo       25  ...
Foo       56  ...
Foo       56  ...
Bar       10  ...
Bar       10  ...
Bar       11  ...
Bar       23  ...

我需要计算从x到x + i的滑动窗口中“Number”列中元素的数量,以确定每个滑动窗口桶中的值的数量。

例如,如果窗口大小为i = 10,从x = 0开始,并且每步增加x,则“Foo”的滑动窗口桶为上述示例的正确结果:

      Foo    Bar

  0    0      2    #(0-10)
  1    0      3    #(1-11)
  2    0      3    #(2-12)
  3    1      3    #(3-13)
  4    1      3    #(4-14)
   .
   .
   .
  20   1      1    #(13-23)
  21   0      1    #(14-24)
  22   1      1    #(15-25)
   . 
   .
   .

答案是df.max()。max - [Window Length]行和len(df.columns)列。

生成类似数据框的玩具代码可能如下:

import pandas as pd
import numpy as np

str_arr = ['Foo','Bar','Python','PleaseHelp']
data1 = np.matrix(np.random.choice(str_arr, 100, p=[0.5, 0.1, 0.1, 0.3])).T
data2 = np.random.randint(100, size=(100,1))
merge = np.concatenate((data1,data2), axis=1)

df = pd.DataFrame(merge, index=range(100), columns=['Type','Number'])
df.sort_values(['Type','Number'], ascending=[True,True], inplace=True)
df = df.reset_index(drop=True)

如何有效地生成这样的列表?

编辑注意:感谢FLab在我澄清我的问题之前回答了我的问题。

1 个答案:

答案 0 :(得分:1)

这是我提出的解决方案。

为方便起见,请强制使用#' Number'列为int。

df['Number'] = df['Number'].astype(int)

定义所有可能的范围:

len_wdw = 10
all_ranges = [(i, i+len_wdw) for i in range(df['Number'].max()-len_wdw)]

现在检查有多少观察结果" Number"在每个范围内:

def get_mask(df, rg):
    #rg is a range, e.g. (10-20)
    return (df['Number'] >= rg[0]) & (df['Number'] <= rg[1])

result = pd.concat({ rg[0] : 
                        df[get_mask(df, rg)].groupby('Type').count()['Number']
                   for rg in all_ranges},
                 axis = 1).fillna(0).T    

对于随机生成的数字,这给出:

    Bar   Foo  PleaseHelp  Python
0   1.0   4.0         3.0     1.0
1   1.0   5.0         2.0     1.0
2   1.0   5.0         3.0     1.0
3   1.0   4.0         3.0     0.0
4   1.0   3.0         3.0     1.0
.....
85  2.0   3.0         4.0     1.0
86  1.0   3.0         3.0     1.0
87  1.0   4.0         3.0     1.0
88  1.0   4.0         4.0     1.0
89  1.0   3.0         5.0     1.0