组中组的长度(在groupby之后应用groupby)

时间:2019-08-01 09:00:13

标签: python pandas pandas-groupby

我正面临下一个问题: 我有多个组(按ID),对于所有这些组,我需要应用以下代码:如果一个组中位置之间的距离在3米之内,则需要将它们加在一起,因此将创建一个新的组(代码来创建我在下面显示的组)。现在,我想要的是一个距离组中的检测次数,因此是该组的长度。

这一切都可行,但是将其应用于ID组后,会给我一个错误。

代码如下:

def group_nearby_peaks(df, col, cutoff=-3.00):
    """
    This function groups nearby peaks based on location.
    When peaks are within 3 meters from each other they will be added together.
    """
    min_location_between_groups = cutoff

    df = df.sort_values('Location')

    return (
        df.assign(
            location_diff=lambda d: d['Location'].diff(-1).fillna(-9999),
            NOD=lambda d: d[col]
                .groupby(d["location_diff"].shift().lt(min_location_between_groups).cumsum())
                .transform(len)
        )
    )
def find_relative_difference(df, peak_col, difference_col):

    def relative_differences_per_ID(ID_df):
        return (
            spoortak_df.pipe(find_difference_peaks)
            .loc[lambda d: d[peak_col]]
            .pipe(group_nearby_peaks, difference_col)
        )

    return df.groupby('ID').apply(relative_differences_per_ID)

我得到的错误如下:

ValueError: No objects to concatenate

在以下示例数据帧中,我希望得到此结果。

    ID  Location
0   1   12.0
1   1   14.0
2   1   15.0
3   1   17.5
4   1   25.0
5   1   30.0
6   1   31.0
7   1   34.0
8   1   36.0
9   1   37.0
10  2   8.0
11  2   14.0
12  2   15.0
13  2   17.5
14  2   50.0
15  2   55.0
16  2   58.0
17  2   59.0
18  2   60.0
19  2   70.0

预期结果:

    ID  Number of detections
0   1   4
1   1   1
2   1   5
3   2   1
4   2   3
5   2   1
6   2   5

1 个答案:

答案 0 :(得分:1)

在3米之内为s创建groupID Location。那些> 3米的将被强制为单个ID,而其他将被重复ID。最后,对IDscount

进行分组
s = df.groupby('ID').Location.diff().fillna(0).abs().gt(3).cumsum()    
df.groupby(['ID',s]).ID.count().reset_index(name='Number of detections').drop('Location', 1)

Out[190]:
   ID  Number of detections
0   1                     4
1   1                     1
2   1                     5
3   2                     1
4   2                     3
5   2                     1
6   2                     4
7   2                     1