#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