根据2列对间隔范围进行分组

时间:2020-05-22 22:21:19

标签: python pandas dataframe

我是需要清理数据的地质学家。 我有一个包含钻孔间隔的.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”,我希望将“ from”和“ to”范围分组/合并为与相同“ interval_type”相关联的连续间隔。可以删除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,但无法弄清楚该怎么做... 提前非常感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

这应该可以解决问题:

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_name添加到了groupby函数中。

答案 1 :(得分:0)

您可以首先建立一个指标列进行分组。然后使用agg合并要往返的子组。

(
    df.assign(ind=df.interval_type.fillna(''))
      .assign(ind=lambda x: x.ind.ne(x.ind.shift(1).bfill()).cumsum())
    .groupby(['hole_name', 'ind'])
    .agg({'from':'first', 'to':'last', 'interval_type': 'first'})
    .reset_index()
    .drop('ind',1)
)

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