熊猫-合并一组列并求和

时间:2018-08-14 07:46:00

标签: python pandas pandas-groupby

我有一套价格和金额-其中amt1是price1的总交易量。

对我来说,价格太精确了,我想根据价格将价格/金额对分组/合并/汇总到等距的存储桶中,然后对金额求和。

例如,我的原始df:

[ion-card {
            position: relative;
            text-align: center;
            img {
                height: 140px !important;
            }
        }

        .card-title {
            position: absolute;
            top: 25%;
            font-size: 1.4em;
            width: 100%;
            font-weight: bold;
            color: #fff;
            padding: 0px 50px;
        }

        .card-subtitle {
            font-size: 1.0em;
            position: absolute;
            top: 52%;
            width: 100%;
            color: #fff;
        }
        .textMiddle {
            background: #1c4d78d9;
            height: 150px;
            top: 0px;
            position: absolute;
            left: auto;
            width: -webkit-fill-available;
        }

        .ItemExpandedData{
            padding: 16px !important;
            transition: 0.2s linear;
        }
        ion-card.card{
            margin: 0;
            border-radius: 0px;
            box-shadow: none
        }][1]

会产生:

index    price1 price2 price3 price4 amt1 amt2 amt3 amt4
1          451    454    462    470   10    1   2   5
2          448    452    458    464   8     2   6   2
3          461    463    468    480   1     3   6   9
4          453    455    471    481   4     3   2   4

几件事要注意:

  • 我选择将10张纸箱装箱。
  • bin1表示440-449。
  • 价格始终按升序排列。
  • 我实际上有500个价格/量对要计算(1000列df),因此需要扩展。
  • 速度实际上是优先事项(尽管乞g不能选择)。

感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

首先创建带有组的扁平化DataFrame,以通过numpy.ravelnumpy.repeat区分行:

a = df.filter(like='price').values.ravel()
b = df.filter(like='amt').values.ravel()
c = np.repeat(np.arange(len(df)), len(df.filter(like='price').columns))
df = pd.DataFrame({'bin':a, 'amt':b, 'g':c})
print (df)
    bin  amt  g
0   451   10  0
1   454    1  0
2   462    2  0
3   470    5  0
4   448    8  1
5   452    2  1
6   458    6  1
7   464    2  1
8   461    1  2
9   463    3  2
10  468    6  2
11  480    9  2
12  453    4  3
13  455    3  3
14  471    2  3
15  481    4  3

然后按cut进行分箱-我尝试按楼层分隔和10进行动态创建标签和箱,然后按sum进行聚合并按unstack进行重塑:

val = (df['bin'] // 10)
labels = np.arange(val.min() * 10, val.max() * 10 + 10, 10)
bins = np.append(labels, val.max() * 10 + 10)

df = (df.groupby(['g', pd.cut(df['bin'], bins=bins, labels=labels, right=False)])['amt'].sum()
       .unstack(fill_value=0))
print (df)
bin  440  450  460  470  480
g                           
0      0   11    2    5    0
1      8    8    2    0    0
2      0    0   10    0    9
3      0    7    0    2    4

最后创建df的预期格式-通过assignjoin原始df用重命名的列添加新列:

cols1 = ['bin{}'.format(x) for x in range(1, len(df.columns) + 1)]
cols2 = ['amt{}'.format(x) for x in range(1, len(df.columns) + 1)]

d1= dict(zip(cols1, df.columns))
d2= dict(zip(df.columns, cols2))

df1 = pd.DataFrame(index=df.index).assign(**d1).join(df.rename(columns=d2))
print (df1)
   bin1  bin2  bin3  bin4  bin5  amt1  amt2  amt3  amt4  amt5
g                                                            
0   440   450   460   470   480     0    11     2     5     0
1   440   450   460   470   480     8     8     2     0     0
2   440   450   460   470   480     0     0    10     0     9
3   440   450   460   470   480     0     7     0     2     4