我有一个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
的组合数量,但不告诉我哪个组合有什么数量。
答案 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