2个大熊猫数据集的条件合并

时间:2021-01-13 18:56:24

标签: python pandas dataframe numpy

我有 2 个数据框,如下所示:

A = pd.DataFrame({'UserId':['U1','U1','U1','U2','U2','U3'],'End_Week':['1/6/2020','15/6/2020','6/7/2020','4/5/2020','18/5/2020','20/4/2020'],'Start_Week':['1/6/2019','15/6/2019','6/7/2019','4/5/2019','18/5/2019','20/4/2019']})

B = pd.DataFrame({'UserId':['U1','U1','U1','U1','U2','U2','U3'],'Action':['U','V','U','U','V','V','U'],'Date':['5/3/2019','4/6/2019','1/7/2019','12/6/2020','4/4/2019','12/5/2019','19/3/2019'],'V1':[2,3,1,2,4,1,1],'V2':[0,1,0,0,1,2,1]})

我想做以下步骤:

对于 'A' 的每一行,从数据框 'B' 中找到所有位于 A 中给出的 Start_Week 和 End_Week 列之间的对应行。例如 - 'A' 的第一行 -> Start_Week 是 '1/6/2019 ' 和 End_Week 是 '1/6/2020'。位于这些日期之间的数据帧“B”中的所有行都是第 2 行和第 3 行,即日期 4/06/2019 和 1/7/2019(对于用户 U1)。必须对数据帧 A 的所有行进行类似的操作。

我有以下解决方案,它适用于小数据,但无法为我正在使用的整个数据分配内存。

a = A.Date.values
a1 = A.UserId.values
b1 = B.UserId.values
bh = B.End_Week.values
bl = B.Start_Week.values

i, j = np.where((a1[:, None]==b1) & (a[:, None] >= bl) & (a[:, None] <= bh))
final_df = pd.DataFrame(np.column_stack([A.values[i], B.values[j]]),columns=A.columns.append(B.columns))

我收到以下错误消息:

MemoryError: Unable to allocate 514. GiB for an array with shape (662195, 834051) and data type bool

在我的数据集中,A 包含 662195 行,B 包含 834051。

有人可以帮助解决此问题的最佳解决方案吗。

1 个答案:

答案 0 :(得分:0)

首先将日期转换为日期时间(如果日期已经是日期时间类型,则忽略此块

<head>
  <script src="jquery-3.5.1.min.js"></script>
</head>
<script>
$('#myform').submit(function(event) {

 event.preventDefault(); //this will prevent the default submit

  window.onbeforeunload = null;
  
 $(this).unbind('submit').submit(); // continue the submit unbind preventDefault
})
<script>

然后 A[['End_Week','Start_Week']] = A[['End_Week','Start_Week']].apply(pd.to_datetime, dayfirst=True) B['Date'] = pd.to_datetime(B['Date'],dayfirst=True) 并使用 merge

series.between

out = B.merge(A,on='UserId',how='left')
out = out[out['Date'].between(u['Start_Week'],u['End_Week'])]

如果你只想要来自 B 的列,你可以过滤输出以只保留来自 B 的列;

print(out)

   UserId Action       Date  V1  V2   End_Week Start_Week
3      U1      V 2019-06-04   3   1 2020-06-01 2019-06-01
6      U1      U 2019-07-01   1   0 2020-06-01 2019-06-01
7      U1      U 2019-07-01   1   0 2020-06-15 2019-06-15
10     U1      U 2020-06-12   2   0 2020-06-15 2019-06-15
11     U1      U 2020-06-12   2   0 2020-07-06 2019-07-06
14     U2      V 2019-05-12   1   2 2020-05-04 2019-05-04