Я пишу сценарий для идентификации кластеров данных в одном измерении (глубине), определяемом указанным пользователем интервалом глубины для нескольких нефтяных скважин. Скрипт проверяет разницу в глубине (d_dep), а затем использует cumsum() для нумерации уникального идентификатора кластера. Я хочу изменить идентификатор кластера, чтобы он начинался с «1» для каждого нового появления колодца (идентификатора). Мой цикл «for» в списке идентификаторов не работает. Кажется, это должно быть простое решение, но, похоже, я что-то упускаю.
# Create Data
data = {'id': [1,1,1,1,1, 2,2,2,2,2, 3,3,3,3,3],
'depth': [1,2,10,11,70, 0,20,75,150,155, 0,100,105,200,210],
'temp': [1,1,1,1,1, 2,2,2,2,2, 3,3,3,3,3],
'surfT': [9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]}
# Create DataFrame
df = pd.DataFrame(data)
# SORT by id and depth
df.sort_values(by=['id', 'depth'], inplace=True, ascending=True)
# df.head(20)
# Create a list of unique IDs
IDs = df['id'].unique()
print('Unique IDs: ', IDs)
# IDENTIFY DATA CLUSTERS BY DEPTH
#===============================================================================================
#1) Calculate the difference in depth between samples, and the first occurence of id is zero
df['d_dep']= np.abs(np.where(df['id'].shift(1) != df['id'], 0, df['depth'].shift(1) - df['depth']))
#2) Flag clusters by depth using the gap threshold
gap= 50 # Gap Theshold
# Flag clusters by the gap threshold, where the d_dep > gap or the first observation in id
df['cluster'] = np.where((df['d_dep']>=gap) | (df['id'].shift(1) != df['id']), 1, 0)
# Assign unique numeric id for clusters of data based on the gap threshold
for i in IDs:
df['cluster_id'] = df['cluster'].cumsum()
display(df)
Я пытался:
for i in IDs:
df['cluster_id'] = df['cluster'].cumsum()
И я получаю следующую таблицу:
Cluster_id для первого идентификатора является правильным, но для идентификаторов с номерами 2 и 3 первый кластер_id должен быть равен 1 и начать отсчет заново.
🤔 А знаете ли вы, что...
С Python можно создавать веб-скраперы для извлечения данных из веб-сайтов.
Если я понимаю, что вам нужно, вы можете использовать:
df['cluster_id'] = df.groupby('id')['cluster'].transform('cumsum')
что дает:
id depth temp surfT d_dep cluster cluster_id
0 1 1 1 9 0.0 1 1
1 1 2 1 9 1.0 0 1
2 1 10 1 9 8.0 0 1
3 1 11 1 9 1.0 0 1
4 1 70 1 9 59.0 1 2
5 2 0 2 9 0.0 1 1
6 2 20 2 9 20.0 0 1
7 2 75 2 9 55.0 1 2
8 2 150 2 9 75.0 1 3
9 2 155 2 9 5.0 0 3
10 3 0 3 9 0.0 1 1
11 3 100 3 9 100.0 1 2
12 3 105 3 9 5.0 0 2
13 3 200 3 9 95.0 1 3
14 3 210 3 9 10.0 0 3