создание фрейма данных и на основе 2 наборов фреймов данных различной длины

#python #dataframe

Вопрос:

У меня есть 2 набора фреймов данных , я хочу создать третий. Я пытаюсь написать код, который выполнял бы следующее : если A_pd[«от»] и A_pd[«До»] находятся в диапазоне B_pd[«от»]и B_pd[«До»], затем добавьте в фрейм данных C_pd A_pd[«от»] и A_pd[«До»] и B_pd[«Значение»].

если A_pd[«от»] находится в диапазоне B_pd[«от»]и B_pd[«До»] и A_pd[«До»] в диапазоне B_pd[«от»]и B_pd[«До»] следующей строки , то я хочу разделить диапазон A_pd[«от»] и A_pd[«До»] на 2 диапазона (A_pd[«от»] и B_pd[«До»]) и ( B_pd[«До»] и A_pd[«Кому»] ) и соответствующий B_pd[«Значение»].

Я создал следующий код:

 import pandas as pd

A_pd = {'from':[0,20,80,180,250],
        'To':[20, 50,120,210,300]}

A_pd=pd.DataFrame(A_pd)

B_pd = {'from':[0,20,100,200],
    'To':[20, 100,200,300],
    'Value':[20, 17,15,12]}
B_pd=pd.DataFrame(B_pd)

for i in range(len(A_pd)):
    numberOfIntrupt=0 
    for j in range(len(B_pd)): 
        if A_pd["from"].values[i] >= B_pd["from"].values[j] and A_pd["from"].values[i] >  B_pd["To"].values[j]:
            numberOfIntrupt =1
cols = ['C_from', 'C_To', 'C_value']
C_dp=pd.DataFrame(columns=cols, index=range(len(A_pd) numberOfIntrupt))           

for i in range(len(A_pd)):
    for j in range(len(B_pd)): 
        a=A_pd ["from"].values[i]
        b=A_pd["To"].values[i]
        c_eval=B_pd["Value"].values[j]
        range_s=B_pd["from"].values[j]
        range_f=B_pd["To"].values[j]
        if a >= range_s and a <=  range_f and b >= range_s and b <=  range_f :
            C_dp['C_from'].loc[i]=a
            C_dp['C_To'].loc[i]=b
            C_dp['C_value'].loc[i]=c_eval
       
        elif a >= range_s and b > range_f:
            C_dp['C_from'].loc[i]=a
            C_dp['C_To'].loc[i]=range_f
            C_dp['C_value'].loc[i]=c_eval
            C_dp['C_from'].loc[i 1]=range_f
            C_dp['C_To'].loc[i 1]=b
            C_dp['C_value'].loc[i 1]=B_pd["Value"].values[j 1]
        

print(C_dp)
 

Текущий результат-C_dp:

 C_from C_To C_value
0      0   20      20
1     20   50      17
2     80  100      17
3    180  200      15
4    250  300      12
5    200  300      12
6    NaN  NaN     NaN
7    NaN  NaN     NaN
 

ожидаемое должно быть :

 C_from C_To C_value
0      0   20      20
1     20   50      17
2     80  100      17
3    100  120      15
4    180  200      15
5    200  210      12
6    250  300     12
 

Большое вам спасибо за поддержку

Комментарии:

1. Ваш вопрос немного неясен, не могли бы вы немного объяснить вопрос.

2. спасибо за ваш ответ, я объясню это в качестве примера : допустим , значение raw в A_pd равно 0,10 , этот диапазон значений находится в пределах первого значения raw в B_pd 0,20,20, поэтому первое значение raw в C_pd будет 0,10, 20 … если значение raw в A_pd равно 80 120, то значение 80 будет больше, чем B_pd. [«от»].значение[1], но 120 больше , чем B_pd. [«до»]. значение[1], поэтому значение 80-120 следует разделить на 80-100 и 100-120, потому что они относятся к разным категориям B_pd. [«ценность»]

Ответ №1:

Я уверен, что есть лучший способ сделать это без циклов, но это поможет вашей логике течь.

 import pandas as pd

A_pd = {'from':[0,  20,  80, 180, 250],
          'To':[20, 50, 120, 210, 300]}

A_pd=pd.DataFrame(A_pd)

B_pd = {'from':[0,  20, 100, 200],
          'To':[20, 100,200, 300],
       'Value':[20, 17,  15,  12]}
B_pd=pd.DataFrame(B_pd)


cols = ['C_from', 'C_To', 'C_value']
C_dp=pd.DataFrame(columns=cols)
spillover = False
for i in range(len(A_pd)):
    for j in range(len(B_pd)):
        a_from = A_pd["from"].values[i]
        a_to = A_pd["To"].values[i]
        b_from = B_pd["from"].values[j]
        b_to = B_pd["To"].values[j]
        b_value = B_pd['Value'].values[j]

        if (a_from >= b_to):
            # a_from outside b range
            continue    # next b
        
        elif (a_from >= b_from):
            # a_from within b range
            if a_to <= b_to:
                C_dp = C_dp.append({"C_from": a_from, "C_To": a_to, "C_value": b_value}, ignore_index=True)
                break   # next a
            else:
                C_dp = C_dp.append({"C_from": a_from, "C_To": b_to, "C_value": b_value}, ignore_index=True)
                if j < len(B_pd):
                    spillover = True
                    continue
        
        if spillover:
            if a_to <= b_to:
                C_dp = C_dp.append({"C_from": b_from, "C_To": a_to, "C_value": b_value}, ignore_index=True)
                spillover = False
                break
            else:
                C_dp = C_dp.append({"C_from": b_from, "C_To": b_to, "C_value": b_value}, ignore_index=True)
                spillover = True
                continue

print(C_dp)
 

Выход

   C_from C_To C_value
0      0   20      20
1     20   50      17
2     80  100      17
3    100  120      15
4    180  200      15
5    200  210      12
6    250  300      12
 

Комментарии:

1. Спасибо @Davis