选定行的 Pandas 数据框聚合

5

我有一个已按时间排序的 pandas 数据框,像这样:

from datetime import datetime
df = pd.DataFrame({ 'ActivityDateTime' : [datetime(2016,5,13,6,14),datetime(2016,5,13,6,16),
                                 datetime(2016,5,13,6,20),datetime(2016,5,13,6,27),datetime(2016,5,13,6,31),
                                 datetime(2016,5,13,6,32),
                                datetime(2016,5,13,17,34),datetime(2016,5,13,17,36),
                                 datetime(2016,5,13,17,38),datetime(2016,5,13,17,45),datetime(2016,5,13,17,47),
                                datetime(2016,5,16,13,3),datetime(2016,5,16,13,6),
                                 datetime(2016,5,16,13,10),datetime(2016,5,16,13,14),datetime(2016,5,16,13,16)],
              'Value1' : [0.0,2.0,3.0,4.0,0.0,0.0,0.0,7.0,8.0,4.0,0.0,0.0,3.0,9.0,1.0,0.0],
               'Value2' : [0.0,2.0,3.0,4.0,0.0,0.0,0.0,7.0,8.0,4.0,0.0,0.0,3.0,9.0,1.0,0.0]
        })

这将变成这样:

ActivityDateTime    Value1  Value2
0   2016-05-13 06:14:00 0.0 0.0
1   2016-05-13 06:16:00 2.0 2.0
2   2016-05-13 06:20:00 3.0 3.0
3   2016-05-13 06:27:00 4.0 4.0
4   2016-05-13 06:31:00 0.0 0.0
5   2016-05-13 06:32:00 0.0 0.0
6   2016-05-13 17:34:00 0.0 0.0
7   2016-05-13 17:36:00 7.0 7.0
8   2016-05-13 17:38:00 8.0 8.0
9   2016-05-13 17:45:00 4.0 4.0
10  2016-05-13 17:47:00 0.0 0.0
11  2016-05-16 13:03:00 0.0 0.0
12  2016-05-16 13:06:00 3.0 3.0
13  2016-05-16 13:10:00 9.0 9.0
14  2016-05-16 13:14:00 1.0 1.0
15  2016-05-16 13:16:00 0.0 0.0

我想聚合数据(求平均)而不使用 for 循环。但是,我将对观察结果进行分组的方式并不简单!查看 Value1,我想将它们作为 非零 值进行分组。例如,索引 1,2,3 将在一个组中。索引 7,8,9 在一个组中,另一个组将是 12,13,14。应避免 value1==0 的行,并且零只是组之间的分隔符。最终,我想获得像这样的东西:

Activity_end    Activity_start  Value1  Value2  num_observations
0   2016-05-13 06:27:00 2016-05-13 06:16:00 4.50    4.50    3
1   2016-05-13 17:45:00 2016-05-13 17:36:00 6.33    6.33    3
2   2016-05-16 13:14:00 2016-05-16 13:06:00 4.33    4.33    3

目前,我在考虑应该给一个新的列分配数字123,然后基于此聚合它们。但是我不确定如何在没有for循环的情况下创建该列!请注意,Value1Value2不一定相同。


它们总是以3个为一组吗?如果是这样,那么您可以只删除所有零行,然后取3个一组。 - Jezzamon
很遗憾,不行 :/ 它们可以以任何数量出现在一个组中。 - ahoosh
1个回答

4
一种方法是创建一些临时列。
# First create a new series, which is true whenever the value changes from a zero value to a non-zero value (which will be at the start of each group)
nonzero = (df['Value1'] > 0) & (df['Value1'].shift(1) == 0)
# Take a cumulative sum. This means each group will have it's own number.
df['group'] = df['nonzero'].cumsum()
# Group by the group column
gb = df[df['Value1'] > 0].groupby('group')

您可以使用聚合函数http://pandas.pydata.org/pandas-docs/stable/groupby.html对这个组进行汇总。
如果您想获得特定的输出结果,请查看这个答案:Python Pandas: Multiple aggregations of the same column
df2 = gb.agg({
    'ActivityDateTime': ['first', 'last'],
    'Value1': 'mean',
    'Value2': 'mean'})

1
太好了,完全有效。我认为 gb = df[df['Value'] > 0].groupby('group') 中有一个错别字,应该是 Value1 - ahoosh
дёҖдёӘеҗҺз»ӯй—®йўҳгҖӮеҒҮи®ҫжҲ‘зҡ„еҲ—дёӯжңүвҖңnanвҖқеҖјгҖӮж №жҚ®й“ҫжҺҘпјҢжҲ‘жӯЈеңЁдҪҝз”Ёnp.nanmeanе’Ң'np.nanmean'пјҢдҪҶе®ғ们йғҪдёҚиө·дҪңз”ЁгҖӮ然иҖҢпјҢеңЁжҲ‘зҡ„з”өи„‘дёҠпјҢnp.nanmean(np.array[1,2,np.nan])е®Ңе…ЁеҸҜд»Ҙе·ҘдҪңгҖӮ - ahoosh
没关系 :) 使用 from functools import partial 然后定义 s_na_mean = partial(pd.Series.mean, skipna = True),我使用它代替 np.nanmean,它可以正常工作。 - ahoosh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接