首页 > 解决方案 > 根据 2 列对区间范围进行分组

问题描述

我是一名需要清理数据的地质学家。我有一个包含钻孔间隔的 .csv 文件,我将其作为 pandas 数据框导入,如下所示:

    hole_name   from    to  interval_type
0   A           0       1   Gold
1   A           1       2   Gold
2   A           2       4   Inferred_fault
3   A           4       6   NaN
4   A           6       7   NaN
5   A           7       8   NaN
6   A           8       9   Inferred_fault
7   A           9       10  NaN
8   A           10      11  Inferred_fault
9   B2          11      12  Inferred_fault
10  B2          12      13  Inferred_fault
11  B2          13      14  NaN

对于每个单独的“hole_name”,我想对与相同“interval_type”关联的连续间隔的“from”和“to”范围进行分组/合并。NaN 值可以删除,它们对我没有用(但我已经知道如何做到这一点,所以没关系)。

基于上面的例子,我想得到这样的东西:

    hole_name   from    to  interval_type
0   A           0       2   Gold
2   A           2       4   Inferred_fault
3   A           4       8   NaN
6   A           8       9   Inferred_fault
7   A           9       10  NaN
8   A           10      11  Inferred_fault
9   B2          11      13  Inferred_fault
11  B2          13      14  NaN

我环顾四周并尝试使用 groupby 或 pyranges 但无法弄清楚如何做到这一点......非常感谢您的帮助!

标签: pythonpandasdataframe

解决方案


这应该可以解决问题:

import pandas as pd
import numpy as np
from itertools import groupby

# create dataframe
data = {
    'hole_name': ['A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B'],
    'from': [0, 1, 2, 4, 6, 7, 8, 9, 10, 11, 12, 13],
    'to': [1, 2, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14],
    'interval_type': ['Gold', 'Gold', 'Inferred_fault', np.nan, np.nan, np.nan, 
                      'Inferred_fault', np.nan, 'Inferred_fault', 'Inferred_fault', 
                      'Inferred_fault', np.nan]
}

df = pd.DataFrame(data=data)

# create auxiliar column that groups repetitive consecutive values
grouped = [list(g) for k, g in groupby(list(zip(df.hole_name.tolist(), df.interval_type.tolist())))]
df['interval_type_id'] = np.repeat(range(len(grouped)),[len(x) for x in grouped])+1

# aggregate results
cols = df.columns[:-1]
vals = []
for idx, group in df.groupby(['interval_type_id', 'hole_name']):
    vals.append([group['hole_name'].iloc[0], group['from'].min(), group['to'].max(), group['interval_type'].iloc[0]])

result = pd.DataFrame(data=vals, columns=cols)
result

result应该:

hole_name   from    to  interval_type
A   0   2   Gold
A   2   4   Inferred_fault
A   4   8   
A   8   9   Inferred_fault
A   9   10  
A   10  11  Inferred_fault
B   11  13  Inferred_fault
B   13  14  

编辑:添加hole_namegroupby功能。


推荐阅读