algorithm - 多渠道联系人问题:根据信息查找相关工单
问题描述
问题描述
以下问题描述取自 Shopee Code League 2021。
对于每个工单,识别每个用户的所有联系人(如果他们具有相同的联系信息)。这些票证中的每一个都通过或直接或间接相关Email
,因此每个票证属于同一用户。例如:Phone
Order ID
票 | ID | 电子邮件 | 订单编号 | 电话 | 联系人 |
---|---|---|---|---|---|
一种 | 0 | john@gmail.com | 12345678 | 不适用 | 5 |
乙 | 1 | 不适用 | 12345678 | 682212345 | 2 |
C | 34567 | wick@gmail.com | 不适用 | 682212345 | 4 |
D | 78999 | wick@gmail.com | 不适用 | 不适用 | 3 |
- 票 A 和 B 是通过链接
Order ID
- 门票 B 和 C 通过
Phone
- 门票 C 和 D 通过
Email
- 票A和D通过票间接链接
A
>>>B
C
D
在这个例子中,这个用户总共有 14 个Contact
。此用户的 ticket_trace/contact 对将是0-1-34567-78999, 14
.
对于每张票,识别ID
属于同一用户的所有其他票,按升序排序,以及Contact
用户拥有的总数。生成具有csv
以下格式的 2 列的文件:
ID | ticket_trace 和联系方式 |
---|---|
0 | 0-1-34567-78999, 14 |
1 | 0-1-34567-78999, 14 |
⋮</td> | ⋮</td> |
请注意,有 500,000 行数据。在短时间内以最少的时间复杂度和内存使用量解决此问题的最有效方法是什么?
问题数据集
输入文件示例contacts.json
:
[
{
"Id":0,
"Email":"gkzAbIy@qq.com",
"Phone":"",
"Contacts":1,
"OrderId":""
},
{
"Id":1,
"Email":"",
"Phone":"329442681752",
"Contacts":4,
"OrderId":"vDDJJcxfLtSfkooPhbYnJdxov"
}, // more data
]
单击此处获取问题数据集和更详细的描述。
解决方案
这是我使用 Python3 的解决方案。我使用了 2 个字典来存储票连接。第一个字典按价值存储连接的票证。第二个字典存储每个 id 连接(跟踪)。最后,使用第二个字典中的跟踪计算联系人。是的,也是一个非常缓慢的方式。它需要3个循环。计算 Kaggle 内核中的所有 500.000 行最多需要 15 秒。
# Import tools
import numpy as np
import pandas as pd
# Load data
df = pd.read_json('/kaggle/input/scl-2021-da/contacts.json')
npdata = df.values
# Initialize memory
memory = {}
connections = {}
# Store connected tickets by value
def add_to_memory(ticket_id, value):
if value != "":
if value in memory:
memory[value].add(ticket_id)
return
memory[value] = {ticket_id}
for row in npdata:
ticket_id = row[0]
# Order Id
add_to_memory(ticket_id, row[4])
# Email
add_to_memory(ticket_id, row[1])
# Phone
add_to_memory(ticket_id, row[2])
# Calculate Trace
for ids in memory.values():
current_connection = set(ids)
for uid in ids:
if uid in connections:
current_connection.update(connections[uid])
for uid in current_connection:
connections[uid] = current_connection
# Calculate contacts and add to list
output = []
for ticket_id, trace in sorted(connections.items()):
contacts = np.sum(npdata[list(trace), 3])
trace = "-".join([str(_id) for _id in sorted(trace)])
answer = "{}, {}".format(trace, contacts)
output.append({"ticket_id": ticket_id, "ticket_trace/contact": answer})
# Convert to pandas DataFrame & save to csv
output_df = pd.DataFrame(output)
filename = "output.csv"
output_df.to_csv(filename, index=False)
推荐阅读
- sql - 带参数存储过程的条件查询
- c# - 使用 Selenium 和 C# 在 Instagram 登录页面中识别用户名字段的 NoSuchElementException
- java - 以编程方式将转换器添加到 Log4j2
- php - 处理来自并发 API 调用的条件 SELECT 和 UPDATE 查询
- apache-kafka - 消息在 kafka 分区中是如何分布的?
- sql-server - 使用 .bak 文件进行 Azure SQL Server 还原
- google-app-engine - 默认情况下,Google App Engine 部署的文件是私有的吗?
- reactjs - reactjs中如何传递下拉参数来获取
- mysql - 将新节点添加到 NDB 集群
- java - Eclipse 中未下载 Maven 依赖项