假设我有一个像这样的csv文件(实际上我有超过100种不同的服务可能):
user_id, services
user_1, "s1,s2,s1,s4,s2,s3,s2"
user_2, "s2,s3,s2,s1,s4"
我想最终拥有这个,如果可能的话主要使用python和pandas:
user_id, c12,c21,c13,c31,c14,c42,c23,c32,c14,c43,c34
user_1, 1,1,0,0,1,1,1,1,0,0,0
user_2, 0,1,0,0,0,0,1,1,1,0,1
其中cij
= sequence si,sj for each user
的数量
理想情况下,我希望它不仅可用于2的序列,还可用于3的序列
我在SO上发现的是si sj的整体计数,但不是像这样的计数。我想在某些时候我需要一个数据透视表,还有n-gram但我不知道如何将它们混合在一起:/
感谢您的帮助
答案 0 :(得分:1)
重新创建数据(但已将服务列拆分为不同的列)
import pandas as pd
df = pd.DataFrame()
df['user_id'] = [1,2]
df['s1'] = [0, 1]
df['s2'] = [1, 1]
df['s3'] = [1,0]
然后我们可以合并:
cols = list(df)[1:]
for c1, c2 in itertools.permutations(c,2):
df[c1+c2] = df[c1] & df[c2]
通过更改2合3,您可以添加3克而不是n-gram。
编辑:
我现在更了解你的问题。下面是一个适用于字符串的解决方案。首先我们创建一些数据:
import pandas as pd
df = pd.DataFrame([['user1',"s1,s2,s1,s4,s2,s3,s2"],['user2',"s2,s3,s2,s1,s4"]])
df.columns = ['userid','services']
对于n-gram,我们使用灵活的功能(如您所示,您可能希望使用更高级别的n-gram)
def find_ngrams(input_list, n):
return zip(*[input_list[i:] for i in range(n)])
我们计算出现次数并创建数据框:
results = {}
for idx, row in df.iterrows():
list_of_services = row['services'].split(',')
combinations = ['c_{}_{}'.format(c1,c2) for c1, c2 in find_ngrams(list_of_services, 2)]
results[row['userid']] = {k: 1 for k in combinations}
df2.from_dict(results).transpose()
对于您的玩具示例,它会返回:
c_s1_s2 c_s1_s4 c_s2_s1 c_s2_s3 c_s3_s2 c_s4_s2
user1 1.0 1.0 1.0 1.0 1.0 1.0
user2 NaN 1.0 1.0 1.0 1.0 NaN
答案 1 :(得分:1)
只需使用python和itertools
即可使用itertools.pairwise
配方执行此操作。
import itertools as it
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = it.tee(iterable)
next(b, None)
return zip(a, b)
假设您正在使用csv.DictReader()
阅读文件,那么:
>>> from collection import Counter
>>> services = ['s1', 's2', 's3', 's4'] # Total set of services
>>> combs = list(it.permutations(services, 2)) # All combinations of services
>>> counts = {row['user_id']: Counter(pairwise(row['services'].split(','))) for row in reader}
>>> [{user: {p: c[p] for p in combs} for user, c in counts.items()}]
[{'user_1': {('s1', 's2'): 1,
('s1', 's3'): 0,
('s1', 's4'): 1,
('s2', 's1'): 1,
('s2', 's3'): 1,
('s2', 's4'): 0,
('s3', 's1'): 0,
('s3', 's2'): 1,
('s3', 's4'): 0,
('s4', 's1'): 0,
('s4', 's2'): 1,
('s4', 's3'): 0},
'user_2': {('s1', 's2'): 0,
('s1', 's3'): 0,
('s1', 's4'): 1,
('s2', 's1'): 1,
('s2', 's3'): 1,
('s2', 's4'): 0,
('s3', 's1'): 0,
('s3', 's2'): 1,
('s3', 's4'): 0,
('s4', 's1'): 0,
('s4', 's2'): 0,
('s4', 's3'): 0}}]