我有 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。
有人可以帮助解决此问题的最佳解决方案吗。
答案 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