2016-07-11 61 views
3

如何映射一个数据帧到另一个DF与更少的行以给定的间隔相加行的值whoose指数是多少?熊猫据帧压缩

例如

鉴于DF:

 Survived 
Age   
20   1 
22   1 
23   3 
24   2 
30   2 
33   1 
40   8 
42   7 

希望的DF

(对于间隔= 5):

 Survived 
Age   
20   7 
25   0 
30   3 
35   0 
40   15 

(对于间隔= 10):

 Survived 
Age   
20   7 
30   3 
40   15 

回答

1

您可以使用函数为groupby参数:

In [6]: df.groupby(lambda x: x//10 * 10).sum() 
Out[6]: 
    Survived 
20   7 
30   3 
40  15 

注意,这也适用于5,但它不工作,你想与空组的方式,也就是说,它不填写零!

In [12]: df.groupby(lambda x: x//5 *5).sum() 
Out[12]: 
    Survived 
20   7 
30   3 
40  15 

但是,如果数据包含5间隔内这些组的值,则可以看到它正在工作。

In [18]: df 
Out[18]: 
    Survived 
Age   
20   1 
22   1 
23   3 
24   2 
26   99 
30   2 
33   1 
40   8 
42   7 
47   99 

In [19]: df.groupby(lambda x: x//5 *5).sum() 
Out[19]: 
    Survived 
20   7 
25  99 
30   3 
40  15 
45  99 
+0

@ОлегСериков你确定jezrael的解决方案不是你所需要的吗? –

+0

我认为最好的是尝试两种解决方案,如果输出是相同的,使用'juanpa.arrivillaga'解决方案,因为没有转换到'timedeltaindex'。如果产出不同,我认为你可以使用我的解决方案。 – jezrael

0

您可以从列Age创建一个新列,然后使用GROUPBY:

为了创建新列,Age需要采取列的索引:

df.reset_index(inplace = True) 


def cat_age(age): 
    return 10*int(age/10.) 

df['category_age'] = df.Age.apply(lambda x: cat_age(x)) 
df.groupby('category_age',as_index = False).agg({'Survived':sum}) 

输出:

category_age Survived 
0 20    7 
1 30    3 
2 40    15 

当然,如果你想改变的类别,你可以通过间隔cat_age

def cat_age(age,interval) 
    return interval*int(1.*age/interval) 
1

首先转换int指数TimedeltaIndex然后resample

df.index = pd.TimedeltaIndex(df.index.to_series(), unit='s') 
print (df) 
      Survived 
00:00:20   1 
00:00:22   1 
00:00:23   3 
00:00:24   2 
00:00:30   2 
00:00:33   1 
00:00:40   8 
00:00:42   7 

df1 = df.resample('5S').sum().fillna(0) 
df1.index = df1.index.seconds 
print (df1) 
    Survived 
20  7.0 
25  0.0 
30  3.0 
35  0.0 
40  15.0 

df2 = df.resample('10S').sum().fillna(0) 
df2.index = df2.index.seconds 
print (df2) 
    Survived 
20   7 
30   3 
40  15 

编辑:

如果Age> 60它的作品太好了:

print (df) 
    Survived 
Age   
20   1 
22   1 
23   3 
24   2 
30   2 
33   1 
40   8 
42   7 
60   8 
62   7 
70   8 
72   7 
df.index = pd.TimedeltaIndex(df.index.to_series(), unit='s') 

df1 = df.resample('5S').sum().fillna(0) 
df1.index = df1.index.seconds 
print (df1) 
    Survived 
20  7.0 
25  0.0 
30  3.0 
35  0.0 
40  15.0 
45  0.0 
50  0.0 
55  0.0 
60  15.0 
65  0.0 
70  15.0 

df2 = df.resample('10S').sum().fillna(0) 
df2.index = df2.index.seconds 
print (df2) 
    Survived 
20  7.0 
30  3.0 
40  15.0 
50  0.0 
60  15.0 
70  15.0 
+1

噢噢。使用'Timedeltaindex'是个好主意。 –

+0

谢谢。你的解决方案也很好,但是可能为interval = 5添加解决方案吗? – jezrael

+0

我编辑了我的答案。也许OP会发现结果可以接受,但像你这样做,他们不完全符合要求的输出。虽然,现在我不知道你怎么会公平时年龄> 60 –