【问题标题】:Get combinations based on a specific column of dataframe in python根据python中数据框的特定列获取组合
【发布时间】:2020-07-21 20:14:40
【问题描述】:

我有一个包含 3 列的数据框:等价、类、通道。我正在使用 Python。

equivalences                             class                                              ch

ETICA CONTABIL                           A ÉTICA CONTÁBIL                                   40.0
ETICA CONTABIL                           A ÉTICA CONTÁBIL COM ENFOQUE                       40.0
BANCO DE DADOS                           GERENCIANDO SEU BD                                 40.0
AMBIENTE WEB                             APLICAÇÕES EM NUVENS                               40.0
AMBIENTE WEB                             ALTA DISPONIBILIDADE                               40.0
TECNOLOGIAS WEB                          PÁGINAS PARA INTERNET                              40.0
TECNOLOGIAS WEB                          PROGRAMAÇÃO WEB AVANÇADA                           40.0
TECNOLOGIAS WEB                          DESENVOLVENDO COM JS                               40.0
None                                     PROGRAMAÇÃO WEB                                    40.0

我需要得到等价的对组合,对这对的 ch 求和。应该是这样的:

equivalences      class a                   class b                                  ch

ETICA CONTABIL    A ÉTICA CONTÁBIL          A ÉTICA CONTÁBIL COM ENFOQUE            80.0
BANCO DE DADOS    GERENCIANDO SEU BD        (null)                                  40.0
AMBIENTE WEB      APLICAÇÕES EM NUVENS      ALTA DISPONIBILIDADE                    80.0
TECNOLOGIAS WEB   PÁGINAS PARA INTERNET     PROGRAMAÇÃO WEB AVANÇADA                80.0
TECNOLOGIAS WEB   PÁGINAS PARA INTERNET     DESENVOLVENDO COM JS                    80.0
TECNOLOGIAS WEB   PROGRAMAÇÃO WEB AVANÇADA  DESENVOLVENDO COM JS                    80.0
(null)            PROGRAMAÇÃO WEB           (null)                                  40.0

我想我必须使用组合 itertools,但我不知道如何按等价分组以获得不同的对。 我该怎么做?

【问题讨论】:

  • 最后一行和带有“BANCO DE DADOS”的行不是一对。这些案例的确切逻辑是什么?
  • 最后一行和带有“BANCO DE DADOS”的行在a类+b类之间不等价。顺便说一句,这些情况可以排除。
  • 已排除 - 您的意思是从结果中删除吗?
  • 是的,它们并不重要,因为它们没有等价物。我想让他们在数据集中检查错误寄存器的情况,例如“技术 -1st períod” - “technologies” - “technologies -2nd”,这可能是相同的等价物,但我会在解决这个问题后处理这些情况第一部分

标签: python pandas combinations itertools


【解决方案1】:

这是一个解决方案(为了清楚起见,分几个步骤):

# create a cross product of classes per "equivalences"
t = pd.merge(df.assign(dummy = 1), df.assign(dummy=1), 
         on = ["dummy", "equivalences"])

# drop items in which the left and the right class are identical
t = t[t.class_x != t.class_y]

# drop duplicates such as x,y vs y,x
t.loc[t.class_x > t.class_y, ["class_x", "class_y"]] = \
    t.loc[t.class_x > t.class_y, ["class_x", "class_y"]].rename(columns = {"class_x": "class_y", "class_y": "class_x"})
t = t.drop_duplicates(subset = ["equivalences", "class_x", "class_y"])


t["ch"] = t.ch_x + t.ch_y
res = t.drop(["ch_x", "dummy", "ch_y"], axis=1)
print(res) 

==>

       equivalences                   class_x                       class_y    ch
1    ETICA CONTABIL          A ÉTICA CONTÁBIL  A ÉTICA CONTÁBIL COM ENFOQUE  80.0
6      AMBIENTE WEB      ALTA DISPONIBILIDADE          APLICAÇÕES EM NUVENS  80.0
10  TECNOLOGIAS WEB  PROGRAMAÇÃO WEB AVANÇADA         PÁGINAS PARA INTERNET  80.0
11  TECNOLOGIAS WEB      DESENVOLVENDO COM JS         PÁGINAS PARA INTERNET  80.0
14  TECNOLOGIAS WEB      DESENVOLVENDO COM JS      PROGRAMAÇÃO WEB AVANÇADA  80.0

【讨论】:

  • 哇。这是一个了不起的解决方案。它没有给我重复的对。非常感谢!
  • 谢谢:) 您介意为后代接受答案(单击灰色复选标记并将其变为绿色)吗?
【解决方案2】:

假设df 是您的数据框,首先使用itertools 在名为pairs 的单独数据框上获取配对组合,如下所示:

import itertools

pairs = df.groupby('equivalences', )['class'].unique().to_frame()
func = lambda x: list(itertools.combinations(x, 2)) if len(x) > 1 else x
pairs['combinations'] = pairs['class'].map(func)

然后应用嵌套的 for 循环来输出每个 equivalencesclass 对的结果,如下所示:

records = []
for i in pairs.index:
    for j in pairs.loc[i, 'combinations']:
        if isinstance(j, tuple):
            records.append(
                {
                    'equivalences': i,
                    'class a': j[0],
                    'class b': j[1],
                    'ch': df.loc[(df['equivalences'] == i) & (df['class'].isin(j)), 'ch'].sum()
                }
            )
        else:
            records.append(
                {
                    'equivalences': i,
                    'class a': j,
                    'class b': 'null',
                    'ch': df.loc[(df['equivalences'] == i) & (df['class'] == j), 'ch'].sum()
                }
            )
            
    
pd.DataFrame.from_dict(records,)

输出:

    equivalences    class a class b ch
0   AMBIENTE WEB    APLICAÇÕES EM NUVENS    ALTA DISPONIBILIDADE    80
1   BANCO DE DADOS  GERENCIANDO SEU BD  null    40
2   ETICA CONTABIL  A ÉTICA CONTÁBIL    A ÉTICA CONTÁBIL COM ENFOQUE    80
3   TECNOLOGIAS WEB PÁGINAS PARA INTERNET   PROGRAMAÇÃO WEB AVANÇADA    80
4   TECNOLOGIAS WEB PÁGINAS PARA INTERNET   DESENVOLVENDO COM JS    80
5   TECNOLOGIAS WEB PROGRAMAÇÃO WEB AVANÇADA    DESENVOLVENDO COM JS    80
6   null    PROGRAMAÇÃO WEB null    40

另一方面,在首先应用groupby 之前,不要忘记将null 值转换为字符串或除None 之外的任何值,因为pandas groupby 不支持分组None然而。完成后,您始终可以将字符串 null 值转换为真实的 None

【讨论】:

  • 谢谢,成功了!它给了我重复的对,但我可以很好地处理它。
  • 没问题。我不确定上述答案是否会产生重复的案例,请您再检查一次吗?我使用itertools.combinations 配对以避免重复的情况。此外,如果您查看答案的输出,它与上述问题中的预期输出相同。无论如何,如果您认为答案有效,请不要忘记投票。
猜你喜欢
  • 1970-01-01
  • 2016-10-08
  • 2023-02-07
  • 1970-01-01
  • 2018-04-02
  • 1970-01-01
  • 2017-07-05
  • 2020-02-24
相关资源
最近更新 更多