我有一个数据框如下
words group_id
0 set([a, c, b, d]) 1
1 set([a, b]) 2
2 set([h, e, g, f]) 3
我需要将行分组为一,即使集合中的一个单词(单词)与另一行中的单词重叠,也要更新group_id。
words group_id
0 set([a, c, b, d]) 1
1 set([a, b]) 1
2 set([h, e, g, f]) 3
我试过这种方式
word_frequency = Counter()
for val in df['words'].values:
word_frequency.update(val)
to_return = np.array(word_frequency.most_common())
count = 1
df['group_id'] = np.zeros(len(df)) * np.nan
for val in to_return:
df['group_id'] = df[['group_id','words']].apply(lambda x: count if (val in x) else np.NAN)
count += 1
我该怎么做?
答案 0 :(得分:1)
这可行,但效率非常低,因为它生成一组唯一的分组,然后为数据帧中的每个条目搜索一组唯一的分组。看到更有效的方法可以很好看。
def unique_grouper(series_of_entry_sets):
set_of_groups = [series_of_entry_sets[0]]
for potential_set in series_of_entry_sets:
for i,accepted_set in enumerate(set_of_groups, start = 1):
if accepted_set & potential_set:
break
else:
set_of_groups.append(potential_set)
break
return set_of_groups
def group_identifier(current_set,set_of_groups):
for i,unique_group in enumerate(set_of_groups):
if current_set & unique_group:
return i
return None
df = pd.DataFrame({"Names":[set(["a", "c", "b", "d"]),set(["a", "b"]),set(["h", "e", "g", "f"]),set(["z"])]})
result =unique_grouper(df.Names)
df["group id"] = df.Names.apply(lambda x:group_identifier(x,result))
输出:
Names group id
0 {a, c, b, d} 0
1 {a, b} 0
2 {h, e, g, f} 1
3 {z} 2
答案 1 :(得分:0)
这是一个非常低效且被黑客攻击的解决方案,但仍有效:
import pandas as pd
df = pd.DataFrame({"Names":[set(["a", "c", "b", "d"]),set(["a", "b"]),set(["h", "e", "g", "f"]),set(["z"])]})
groups={}
idx=0
data=[]
for row in df.itertuples():
values = row.Names
groups[idx] = values
for i in range(len(groups)):
if len(values.intersection(groups[i])) > 0:
not_found = False
data.append(i)
if len(groups[i]) - len(groups[idx]) > 0:
groups[i] = values #Replace with the larger set
if idx>0:
groups.pop(idx, None)
idx-=1
else:
not_found = True
break
break
if not_found:
data.append(idx)
idx+=1
df['group id'] = data
结果:
Names group id
0 {c, d, a, b} 0
1 {a, b} 0
2 {e, h, f, g} 1
3 {z} 2
您仍然应该使用apply方法,而不是遍历数据框中的每一行。