我有以下用例:
我想创建一个数据框,其中每一行都有一列,我可以在其中查看类别中该ID(用户)的互动次数。对我来说最难的是,它们不能被重复计算,而仅其中一个类别的匹配就可以算作1。
例如,我有:
richtingen id
0 Marketing, Sales 1110
1 Marketing, Sales 1110
2 Finance 220
3 Marketing, Engineering 1110
4 IT 3300
现在,我想创建第三行,在这里我可以看到该ID与这些类别中的任何类别进行了总计多少次交互。每个逗号都是一个单独的类别,例如:“市场营销,销售”是市场营销和销售两个类别。要获得+1,您只需要与ID相同且其中一个类别匹配的另一行进行匹配,例如对于索引0,它将为3(索引0、1和3匹配)。该示例的输出数据应为:
richtingen id freq
0 Marketing, Sales 1110 3
1 Marketing, Sales 1110 3
2 Finance 220 1
3 Marketing, Engineering 1110 3
4 IT 3300 1
对我来说,困难的部分似乎是我无法将所有类别都添加到新行中,因为那样的话,您也许会开始数倍。例如,索引0与索引1的“市场营销”和“销售”都匹配,而我只希望它加1,而不是2。
到目前为止,我的代码是:
df['freq'] = df.groupby(['id', 'richtingen'])['id'].transform('count')
这仅匹配相同的类别组合。
我尝试过的其他方法: -创建一个将所有空缺都分成一个数组的新列:
df['splitted'] = df.richtingen.apply(lambda x: str(x.split(",")))
然后计划将这段代码中的某些内容与id上的groupby结合使用,以计算每个项目为true的次数:
if any(t < 0 for t in x):
# do something
我也无法使它正常工作。
例如,使用建议的代码:
df['richtingen'].str.split(', ',expand=True)
请给我以下内容:
0 1 id
0 Marketing Sales 1110
1 Marketing Sales 1110
2 dDD None 220
3 Marketing Engineering 1110
4 ddsad None 3300
但是接下来,我将需要创建遍历每一行的代码,然后检查ID,在各列中列出值,并检查它们是否包含在其他任何列(ID相同)中,以及是否其中匹配项将1加到频率。我怀疑这段代码可以与groupby一起使用,但是不确定,也无法弄清楚。
我认为这种解决方案可能与此类似,但是目前它计算的是唯一类别的总数(而不是与类别互动的唯一次数)。例如,此处索引2的输出为2,而应为1(因为用户只与类别进行了一次交互)。
richtingen id freq
0 Marketing, Sales 1110 3
1 Marketing, Sales 1110 3
2 Finance, Accounting 220 2
3 Marketing, Engineering 1110 3
4 IT 3300 1
希望我让自己清楚了,任何人都知道该如何解决!总共大约有13个类别,总是在一个单元格中,但用逗号分隔。
对于msr_003:
id richtingen freq_x freq_y
0 220 Finance, IT 0 2
1 1110 Finance, IT 1 2
2 1110 Marketing, Sales 2 4
3 1110 Marketing, Sales 3 4
4 220 Marketing 4 1
5 220 Finance 5 2
6 1110 Marketing, Sales 6 4
7 3300 IT 7 1
8 1110 Marketing, IT 8 4
答案 0 :(得分:3)
如果需要先计算id
中每个split
的唯一类别,请按stack
创建MultiIndex Series
,最后将SeriesGroupBy.nunique
与map
一起用于新列DataFrame
的原始版本:
s = (df.set_index('id')['richtingen']
.str.split(', ',expand=True)
.stack()
.groupby(level=0)
.nunique())
print (s)
id
220 1
1110 3
3300 1
dtype: int64
df['freq'] = df['id'].map(s)
print (df)
richtingen id freq
0 Marketing, Sales 1110 3
1 Marketing, Sales 1110 3
2 Finance 220 1
3 Marketing, Engineering 1110 3
4 IT 3300 1
详细信息:
print (df.set_index('id')['richtingen'].str.split(', ',expand=True).stack())
id
1110 0 Marketing
1 Sales
0 Marketing
1 Sales
220 0 Finance
1110 0 Marketing
1 Engineering
3300 0 IT
dtype: object
答案 1 :(得分:0)
我不喜欢大熊猫。但我认为您可能会感到幸运,可以根据Richtingen添加13个新列,每个列包含1个类别或不包含任何类别。创建列时,可以使用dataframe.apply或类似的函数来计算值。
然后您可以通过对ORing进行操作...
答案 2 :(得分:0)
我刚刚如下修改了您的代码。
count_unique = pd.DataFrame({'richtingen' : ["Finance, IT","Finance, IT", "Marketing, Sales", "Marketing, Sales", "Marketing","Finance", "Marketing, Sales", "IT", "Marketing, IT"], 'id': [220,1110,1110, 1110,220, 220,1110,3300,1110]})
count_unique['freq'] = list(range(0,len(count_unique)))
grp = count_unique.groupby(['richtingen', 'id']).agg({'freq' : 'count' }).reset_index(level = [0,1])
pd.merge(count_unique,grp, on = ('richtingen','id'), how = 'left')