在大型数据集中创建组合并维护组合计数

时间:2017-03-03 19:32:09

标签: python pandas

我有一个docker run --privileged ... ,如下所示:

DataFrame

有超过350,000个memberid created firstencodedid questionid 123 <some date> <some ID> 4fc 123 <some date> <some ID> daf 123 <some date> <some ID> f82 123 <some date> <some ID> cfd 123 <some date> <some ID> 730 值和超过100,000 memberid个值,questionid的长度超过45百万条记录。

对于每个DataFrame值,我想生成memberid的所有可能组合,并保持每个'对'的计数。

“对”是指每个questionid彼此配对questionid,对于特定的questionid

例如,以下是显示的数据集中memberid memberid的所有“对”:

123

因此,作为第一步,我尝试生成所有问题对。 RAM(16GB)显然无法保存这些数据,所以我想使用以下代码将这些数据('问题对')写入文件:

['4fc','daf']
['4fc','f82']
['4fc','cfd']
['4fc','730']
['daf','f82']
['daf','cfd']
['daf','730']
['f82','cfd']
['f82','730']
['cfd','730']

此代码有效,但它生成了210GB的文件,然后我的磁盘空间不足。显然,在成功写入文件后计算每个“对”的计数,但这种情况没有发生。

我尝试了另一种尝试使用以下代码创建import itertools import csv start_time = time.time() def generate_combination_of_questions(dataframe): return [ pair for _, questions in dataframe.groupby('memberid') for pair in itertools.combinations(questions.questionid, 2) ] with open('file_name', 'wb') as f: writer = csv.writer(f) for memberid in IncorrectQuestions['memberid'].unique(): for pair in generate_combination_of_questions(IncorrectQuestions[IncorrectQuestions['memberid']==memberid]): writer.writerow(pair) print("--- %s seconds ---" % (time.time() - start_time)) 的方法:

OrderedCounter

这种方法结果非常慢,我也很确定我的记忆会在某些时候放弃。

鉴于这个庞大的数据集,创建这些“问题对”并保持每个“问题对”计数的最佳方法是什么?

非常感谢任何帮助。

TIA。

修改

我不想将整个数据集保留在内存中,但我想知道每个from collections import Counter, OrderedDict class OrderedCounter(Counter, OrderedDict): pass from collections import Counter q1AndQ2Occurrences = OrderedCounter() for memberid in IncorrectQuestions['memberid'].unique(): subset_IncorrectQuestions = IncorrectQuestions[IncorrectQuestions['memberid'] == memberid] q1AndQ2Occurrences = q1AndQ2Occurrences + OrderedCounter(generate_combination_of_questions(subset_IncorrectQuestions)) 值的每个组合的计数。某些组合可能会重复memberid个值,我想添加这些计数。

@Boud的解决方案告诉我每个memberid的组合数量,但不告诉我哪个组合有什么数量。

2 个答案:

答案 0 :(得分:0)

为什么要创建大量的数据来计算它们而不是应用组合数学函数?????

import scipy as sp

N = df.groupby('memberid').questionid.count()
N.apply(lambda x : sp.misc.comb(x, 2))
Out[10]: 
          questionid
memberid            
123             10.0

答案 1 :(得分:0)

同意@Boud关于在内存中存储列表的必要性。但是如果你必须这样做,请考虑这样的数据框:

d = {'memberid': [123,123,123,456,456], 'questionid': ['4fc', 'daf', 'f82', 'cfd', '730']}
df = pd.DataFrame(d)


    memberid    questionid
0   123         4fc
1   123         daf
2   123         f82
3   456         cfd
4   456         730

你可以

df.groupby('memberid').apply(lambda x: list(combinations(x['questionid'], 2)))

它会给你

memberid
123    [(4fc, daf), (4fc, f82), (daf, f82)]
456                            [(cfd, 730)]

编辑:

您可以像这样获得每个memberid的组合数:

df.groupby('memberid').apply(lambda x: len(list(combinations(x['questionid'], 2))))

它会返回

memberid
123        3
456        1
dtype: int64