pandas如何按照别名alias进行分组合并

1、条件:
根据两行中的alias是否有交集,如果有交集,则以#号相隔进行合并
其中:alias中以#号分隔别名
2、数据
name alias
0 土豆 地豆#地蛋#马铃薯#土豆
1 马铃薯 薯仔#马铃薯
2 玉米 棒子#包谷#玉米#玉米
3 薯仔 薯仔
4 包谷 包谷#玉米

clipboard.png

3、最终结果
name alias
土豆#马铃薯#薯仔 地豆#地蛋#马铃薯#土豆#薯仔
玉米#包谷 棒子#包谷#玉米#玉米
clipboard.png

即第1、2、4合并,3、5合并(以#号合并,并去重复)

cols = ['name', 'alias']
data = [['土豆',‘地豆#地蛋#马铃薯#土豆’],
['马铃薯', '薯仔#马铃薯'],
['玉米', '棒子#包谷#玉米#玉米'],
['薯仔', '薯仔'],
['包谷', '包谷#玉米']]
frame = pd.DataFrame(data,columns=cols)

阅读 5.1k
2 个回答
import pandas as pd
import operator
from collections import Counter

cols = ['name', 'alias']
data = [
    ['土豆', '地豆#地蛋#马铃薯#土豆'],
    ['马铃薯', '薯仔#马铃薯'],
    ['玉米', '棒子#包谷#玉米#玉米'],
    ['薯仔', '薯仔'],
    ['包谷', '包谷#玉米']
]

df = pd.DataFrame(data, columns=cols)

#统计重复出现的值列表
inter_lst = reduce(operator.add, df['alias'].apply(lambda x: x.split('#')))
for k, v in Counter(inter_lst).iteritems():
    if v == 1:
        continue

    #找出包含重复值的行并删除
    df1 = df[df['alias'].str.contains(k)]
    df = df.drop(df1.index)

    #构建新行
    name_lst = reduce(operator.add, df1['name'].apply(lambda x: x.split('#')))
    alias_lst = reduce(operator.add, df1['alias'].apply(lambda x: x.split('#')))

    name = '#'.join(list(set(name_lst)))
    alias = '#'.join(list(set(alias_lst)))

    #添加新行
    df = df.append(pd.Series(dict(name=name, alias=alias)), ignore_index=True)

print df
import pandas as pd
cols = ['name', 'alias']
data = [['土豆','地豆#地蛋#马铃薯#土豆'],
['马铃薯', '薯仔#马铃薯'],
['玉米', '棒子#包谷#玉米#玉米'],
['薯仔', '薯仔'],
['包谷', '包谷#玉米']]
frame = pd.DataFrame(data,columns=cols)

d=frame.set_index('name').to_dict()['alias'] # 转成dict处理
k,v = [], []
for i in d:
    print(k, v)
    sv = set(d[i].split('#'))
    cf, cfi = False, None # 重复标志
    for j in range(len(v)):
        if i in v[j]:
            k[j].add(i)
            v[j].update(sv)
            cf, cfi = True, j
            break
    if cf:
        remove = []
        for j in range(len(v)):
            if j != cfi and k[j] & v[cfi]:
                remove.insert(0, j)
                k[cfi].update(k[j])
                v[cfi].update(v[j])
        for j in remove:
            k.pop(j)
            v.pop(j)
    else:
        k.append(set([i]))
        v.append(sv)

frame = pd.DataFrame({'name':['#'.join(i) for i in k], 'alias':['#'.join(i) for i in v]})
print(frame)
             alias       name
0         包谷#棒子#玉米      包谷#玉米
1  薯仔#马铃薯#地蛋#土豆#地豆  薯仔#土豆#马铃薯
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题