【问题标题】:Map frequency of occurrences in a Pandas column to a dictionary将 Pandas 列中出现的频率映射到字典
【发布时间】:2020-08-18 06:17:59
【问题描述】:

我有一个 Pandas 数据框 df,其中包含这些列 -

Quiz          Question         K
  1              1           XYZ-01
  1              2           XXY-07
  1              2           XXP-05
  2              1           PQR-02
  2              1           WXY-09
  2              2           PQR-09
  2              3           XXY-07
  2              3           XXP-05

我想制作一个字典,其中包含Ks 在同一测验中的所有唯一组合作为键,并将它们的出现频率作为值。例如。对于上述 df,dict_combinations 应该类似于 -

{('XYZ-01', 'XXY-07'): 2, ('XXY-07', 'XXP-05'): 2, ('XYZ-01', 'XXP-05'): 1,       # for Quiz 1
 ('PQR-02', 'WXY-09'): 1, ('PQR-02', 'PQR-09'): 1, ('PQR-02', 'XXY-07'): 1, ('PQR-02', 'XYZ-01'): 1, # for Quiz 2 
 ('WXY-09', 'PQR-09'): 1, ('WXY-09', 'XXY-07'): 1, ('WXY-09', 'XXP-05'): 1, ('PQR-09', 'XXY-07'): 1,
 ('PQR-09', 'XXP-05'): 1}

我该怎么做?

【问题讨论】:

  • @jezrael 因为Ks 的组合出现了两次,一次在测验 1 中,一次在测验 2 中。
  • 是的,对不起!现已更正!
  • 看来('XYZ-01', 'XXY-07'): 2应该是('XYZ-01', 'XXY-07'): 1

标签: python python-3.x pandas dataframe dictionary


【解决方案1】:

使用DataFrame.dropna 删除可能的缺失值,然后使用DataFrame.sort_values 并在lambda 函数中为每个组创建2 的组合,通过Series.explode 展平嵌套元组,最后通过Series.value_counts 计算并转换为字典:

from  itertools import combinations

d = (df.dropna(subset=['K'])
        .sort_values(['Quiz','K'])
        .groupby('Quiz')['K'].apply(lambda x: list(combinations(x, 2)))
        .explode()
        .value_counts()
        .to_dict()
        )
print (d)
{('XXP-05', 'XXY-07'): 2, ('WXY-09', 'XXY-07'): 1, ('PQR-02', 'PQR-09'): 1,
 ('PQR-09', 'WXY-09'): 1, ('XXY-07', 'XYZ-01'): 1, ('PQR-02', 'XXY-07'): 1,
 ('PQR-09', 'XXP-05'): 1, ('PQR-02', 'WXY-09'): 1, ('PQR-09', 'XXY-07'): 1, 
 ('WXY-09', 'XXP-05'): 1, ('PQR-02', 'XXP-05'): 1, ('XXP-05', 'XYZ-01'): 1}

另一个想法是使用Counter 作为字典:

from  itertools import combinations
from collections import Counter

L = [tuple(sorted(y)) for i,x in df.dropna(subset=['K']).groupby('Quiz') 
                      for y in combinations(x['K'], 2)]
d = dict(Counter(L))
print (d)
{('XXY-07', 'XYZ-01'): 1, ('XXP-05', 'XYZ-01'): 1, ('XXP-05', 'XXY-07'): 2, 
 ('PQR-02', 'WXY-09'): 1, ('PQR-02', 'PQR-09'): 1, ('PQR-02', 'XXY-07'): 1, 
 ('PQR-02', 'XXP-05'): 1, ('PQR-09', 'WXY-09'): 1, ('WXY-09', 'XXY-07'): 1, 
 ('WXY-09', 'XXP-05'): 1, ('PQR-09', 'XXY-07'): 1, ('PQR-09', 'XXP-05'): 1}

编辑:explode 工作原理:

它扁平化Series 中的嵌套元组列表:

s = (df.dropna(subset=['K'])
        .sort_values(['Quiz','K'])
        .groupby('Quiz')['K'].apply(lambda x: list(combinations(x, 2)))
        # .explode()
        # .value_counts()
        # .to_dict()
        )
print (s)
Quiz
1    [(XXP-05, XXY-07), (XXP-05, XYZ-01), (XXY-07, ...
2    [(PQR-02, PQR-09), (PQR-02, WXY-09), (PQR-02, ...
Name: K, dtype: object

s = (df.dropna(subset=['K'])
        .sort_values(['Quiz','K'])
        .groupby('Quiz')['K'].apply(lambda x: list(combinations(x, 2)))
        .explode()
        )
print (s)
Quiz
1    (XXP-05, XXY-07)
1    (XXP-05, XYZ-01)
1    (XXY-07, XYZ-01)
2    (PQR-02, PQR-09)
2    (PQR-02, WXY-09)
2    (PQR-02, XXP-05)
2    (PQR-02, XXY-07)
2    (PQR-09, WXY-09)
2    (PQR-09, XXP-05)
2    (PQR-09, XXY-07)
2    (WXY-09, XXP-05)
2    (WXY-09, XXY-07)
2    (XXP-05, XXY-07)
Name: K, dtype: object

【讨论】:

  • 第一种方法有效。有没有办法删除其中一个元组元素是 nan 的字典条目?我的数据框中的一些行是nan...
  • @harry04 - 然后在我的解决方案之前使用df = df.dropna(subset=['K']) 删除K 中缺少值的行
  • 太棒了!这对我行得通。谢谢!你能告诉我explode()在这里是如何工作的吗?
  • @harry04 - 添加到回答中。
  • 知道了!谢谢! :)
猜你喜欢
  • 2016-09-02
  • 2021-08-31
  • 1970-01-01
  • 2023-02-21
  • 2021-04-18
  • 2020-09-01
  • 2021-12-27
  • 1970-01-01
  • 2010-12-31
相关资源
最近更新 更多