建立在这个答案 https://stackoverflow.com/questions/58570888/combine-two-dataframes-based-on-ranges-which-may-partially-overlap-using-pandas/58572420#58572420
我有两个大数据框(100K 行),df Assay 有值,df Strat 有“类型”。我想根据深度将 Strat 中的“类型”分配给 Assay 中的列。深度以深度“From”和深度“To”列给出。 “类型”也由深度“From”和“To”定义。但它们的间隔不同。测定深度可以跨越多种 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%
我的尝试如下,但不起作用。我不太擅长循环,并且进行了一些有希望的尝试,但代码似乎会永远运行(注意,我的实际数据集约为 100k 行和 1500 个 HOLE_ID,因此对我的系统的要求可能相当高)。
我添加了 np.arange ,以便我可以使用浮点数(0.1 m 增量来生成辅助序列),并且我认为我已经计算了百分比,但我有点超出了我的深度。
进行一些预处理,以确保仅使用匹配的孔 ID(实际数据很大,并且还包含示例数据集中未包含的其他列。)
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
then:
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
then:
assay['Type'] = assay.groupby('HOLE_ID').apply(getType)
谁能明白为什么这不起作用?