Опираясь на этот ответ
У меня есть два больших фрейма данных (100K строк), у df Assay есть значения, у df Strat есть 'Types'. Я хочу назначить «Тип» из Strat для столбца в Assay на основе глубины. Глубины указаны в столбцах «От» и «До». «Типы» также определяются глубиной «От» и «До». НО они НЕ одинаковые интервалы. Глубина анализа может охватывать несколько типов Strat.
Я хочу назначить Strat 'типы' для Assay df, и, если существует несколько типов, попробуйте также захватить эту информацию.
Я хочуцикл по данным, чтобы заполнить столбец Тип для каждого HOLE_ID.
Создать пример данных:
import pandas as pd
import numpy as np
Assay=pd.DataFrame(np.array([['Hole_1',1.0,2.5,0.001],['Hole_1',2.5,5.0,0.005],['Hole_1',5.0,7.0,0.002],['Hole_1',7.0,10.0,0.001],['Hole_2',1.0,3.0,0.001],['Hole_2',3.0,5.0,0.005],['Hole_2',5.0,7.0,0.002],['Hole_2',7.0,10.0,0.001]]),columns=['HOLE_ID','FROM', 'TO', 'val'])
Strat=pd.DataFrame(np.array([['Hole_1',0.0,4.0,'A'],['Hole_1',4.0,5.0,'B'],['Hole_1',5.0,6.5,'C'],['Hole_1',6.5,8.0,'D'],['Hole_1',8.0,10.0,'E'],['Hole_2',0.0,4.0,'A'],['Hole_2',4.0,5.1,'B'],['Hole_2',5.1,6.0,'C'],['Hole_2',6.0,8.0,'D'],['Hole_2',8.0,10.0,'E']]),columns=['HOLE_ID','FROM', 'TO', 'Type'])
Assay
Out[1]:
HOLE_ID FROM TO val
0 Hole_1 1.0 2.5 0.001
1 Hole_1 2.5 5.0 0.005
2 Hole_1 5.0 7.0 0.002
3 Hole_1 7.0 10.0 0.001
4 Hole_2 1.0 3.0 0.001
5 Hole_2 3.0 5.0 0.005
6 Hole_2 5.0 7.0 0.002
7 Hole_2 7.0 10.0 0.001
Strat
Out[2]:
HOLE_ID FROM TO Type
0 Hole_1 0.0 4.0 A
1 Hole_1 4.0 5.0 B
2 Hole_1 5.0 6.5 C
3 Hole_1 6.5 8.0 D
4 Hole_1 8.0 10.0 E
5 Hole_2 0.0 4.0 A
6 Hole_2 4.0 5.1 B
7 Hole_2 5.1 6.0 C
8 Hole_2 6.0 8.0 D
9 Hole_2 8.0 10.0 E
Пример желаемого результата:
HOLE_ID FROM TO val Type
0 Hole_1 1.0 2.5 0.001 A 100%
1 Hole_1 2.5 5 0.005 A 60%,B 44%
2 Hole_1 5.0 7.0 0.002 C 80%, D 20%
3 Hole_1 7.0 10.0 0.001 D 30%, E 70%
4 Hole_2 1.0 3.0 0.001 A 100%
5 Hole_2 3.0 5.0 0.005 A 50%, B50%
6 Hole_2 5.0 7.0 0.002 B 5%, C 45%, D 50%
7 Hole_2 7.0 10.0 0.001 D 30% E 70%
Моя попытка приведена ниже, но не работает. Я не очень хорош в циклах, и у меня было несколько многообещающих попыток, но казалось, что код работает вечно (обратите внимание, мой фактический набор данных составляет ~ 100 тыс. Строк и 1500 HOLE_ID, поэтому может быть довольно требовательным в моей системе).
Я добавил np.arange, чтобы я мог использовать поплавки (с шагом 0,1 м для генерации вспомогательных рядов), и я думаю, что у меня есть проценты для расчета, но я немного не в своей глубине.
Немного предварительной обработки, чтобы убедиться, что используются только совпадающие идентификаторы отверстий (реальные данные большие, а также содержат дополнительные столбцы, не включенные в примерный набор данных.)
assay_Hole_IDs =Assay['HOLE_ID'].unique().tolist()
strat_Hole_IDS =Strat['HOLE_ID'].unique().tolist()
Strat=Strat[Strat['HOLE_ID'].isin(assay_Hole_IDs)]
Assay=Assay[Assay['HOLE_ID'].isin(assay_Hole_IDs)]
assay_Hole_IDs =Assay['HOLE_ID'].unique().tolist()
strat_Hole_IDS =Strat['HOLE_ID'].unique().tolist()
убедитесь, что нет дополнительных значений
j=set(assay_Hole_IDs).symmetric_difference(set(strat_Hole_IDS))
print len(j)
j
, затем:
all_holes= Strat['HOLE_ID'].unique().tolist()
def getType(row):
for hole in all_holes:
df=Strat.loc[Strat['HOLE_ID']==hole]
units = df.set_index('Type').apply(lambda row: pd.Series(
np.arange(row.FROM, row.TO,0.1)), axis=1).stack()\
.reset_index(level=1, drop=True)
gr = units[units.ge(row.FROM) & units.lt(row.TO)].groupby(level=0)
if gr.ngroups == 1:
return gr.ngroup().index[0]
txt = []
counts = []
pct=[]
for key, grp in gr:
siz = grp.size
un = 'unit' if siz == 1 else 'units'
counts.append(float(siz))
for x in counts:
p=(float(x)/float(sum(counts))*100)
pct.append(float(p))
return pct
затем:
assay['Type'] = assay.groupby('HOLE_ID').apply(getType)
Кто-нибудь может понять, почему это не работает?