我有5000万行数据,如:
referring_id,referred_id
1000,1001
1000,1002
1001,1000
1001,1002
1002,1003
目标是找到共享传入连接的所有案例,数值示例应该有所帮助:
如果我们想要计算 1001 的度量,我们可以看到它有1000的传入,所以我们看看还有哪些来自1000的传入连接,那就是1002。 因此结果将是 [1002] 。
对于 1002 ,我们可以看到1000和1001指的是1002,这意味着我们看看他们引用了谁;结果为 [1001,1000] (1000表示1001,1001表示1000)。
如果它是较小的数据,我只会为每个referring
存储一组传出连接,然后循环遍历referred
并对所有具有传入连接的那些进行联合。
问题是这不适合记忆。
我正在使用csv
遍历文件并一次处理一行,而不是将其加载到内存中,即使我有16GB内存。
有没有人知道如何处理它?
答案 0 :(得分:1)
您应该尝试pandas。它使用NumPy数组来存储数据。这有助于节省内存。例如,一个整数的大小为8个字节,而不是Python 2中的24个或Python 3中的28个。如果数字很小,您可以使用np.int16
或np.int32
来减小大小每个整数2到4个字节。
此解决方案似乎符合您的描述:
s = """referring_id,referred_id
1000,1001
1000,1002
1001,1000
1001,1002
1002,1003"""
import csv
import numpy as np
pd.read_csv(io.StringIO(s), dtype=np.int16)
# use: df = pd.read_csv('data.csv', dtype=np.int16)
by_refered = df.groupby('referred_id')['referring_id'].apply(frozenset)
by_refering = df.groupby('referring_id')['referred_id'].apply(frozenset)
with open('connections.csv', 'w') as fobj:
writer = csv.writer(fobj)
writer.writerow(['id', 'connections'])
for x in by_refered.index:
tmp = set()
for id_ in by_refered[x]:
tmp.update(by_refering[id_])
tmp.remove(x)
writer.writerow([x] + list(tmp))
connections.csv
的内容:
id,connections
1000,1002
1001,1002
1002,1000,1001
1003
根据您的数据,您可能会使用此功能。如果有许多重复连接,则组的数量及其大小可能足够小。否则,您需要使用一些分块方法。