计算不存在值的频率

2024-06-08 09:14:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用pyreadstat打开一个SPSS(.sav)文件,想象一个数据框,其中的列是来自调查的问题。我想通过首先融合数据,然后计算频率,来计算由其他列分组的每一列的频率

import pandas as pd
import pyreadstat


df, meta = pyreadstat.read_sav('df_test.sav')
questions = ['q1', 'q2', 'q3']

df_m = df.melt(value_vars=questions, var_name='question', id_vars=['yearmonth','grp']).dropna()
df_m.groupby(['yearmonth', 'grp', 'question', 'value']).agg({'value': 'count'})

这将为我们提供如下良好的输出:

                               value
yearmonth grp  question value       
2020-08   Grp1 q1       1.0        1
               q2       1.0        1
               q3       1.0        1
2020-09   Grp1 q1       1.0       50
                        2.0        4
                        4.0        3
               q2       1.0       42
                        2.0       12
               q3       1.0       52
                        2.0        2
          Grp2 q1       1.0       98
                        3.0        2
                        4.0        1
               q2       1.0       89
                        2.0        6
               q3       1.0       86
                        2.0        9

但这里有个棘手的部分。我知道q1有5个不同的答案(1,2,3,4,5),但显然除了1,3或4没有人回答任何问题,q2也有5个不同的答案,但q3有3个不同的答案。我希望为不存在的值提供输出0,因此看起来如下所示:

                               value
yearmonth grp  question value       
2020-08   Grp1 q1       1.0        1
               q1       2.0        0
               q1       3.0        0
               q1       4.0        0
               q1       5.0        0
....................................
....................................
....................................
               q3       1.0       86
                        2.0        9
                        3.0        0

pyreadstat有一个很好的特性,您可以从.sav文件中读取meta,变量值及其值标签:

{'q1': {1.0: '1', 2.0: '2', 3.0: '3', 4.0: '4', 5.0: '5'},
 'q2': {1.0: '1', 2.0: '2', 3.0: '3', 4.0: '4', 5.0: '5'},
 'q3': {1.0: '1', 2.0: '2', 3.0: '3'}}

df_m.groupby dict:

{'value': {('2020-08', 'Grp1', 'q1', 1.0): 1,
  ('2020-08', 'Grp1', 'q2', 1.0): 1,
  ('2020-08', 'Grp1', 'q3', 1.0): 1,
  ('2020-09', 'Grp1', 'q1', 1.0): 50,
  ('2020-09', 'Grp1', 'q1', 2.0): 4,
  ('2020-09', 'Grp1', 'q1', 4.0): 3,
  ('2020-09', 'Grp1', 'q2', 1.0): 42,
  ('2020-09', 'Grp1', 'q2', 2.0): 12,
  ('2020-09', 'Grp1', 'q3', 1.0): 52,
  ('2020-09', 'Grp1', 'q3', 2.0): 2,
  ('2020-09', 'Grp2', 'q1', 1.0): 98,
  ('2020-09', 'Grp2', 'q1', 3.0): 2,
  ('2020-09', 'Grp2', 'q1', 4.0): 1,
  ('2020-09', 'Grp2', 'q2', 1.0): 89,
  ('2020-09', 'Grp2', 'q2', 2.0): 6,
  ('2020-09', 'Grp2', 'q3', 1.0): 86,
  ('2020-09', 'Grp2', 'q3', 2.0): 9}}

我可以用这个dict来计算数据帧中不存在的值的频率吗?或者将不存在的值插入到分组的帧中


Tags: 数据答案dfvalue频率questionsavq3
2条回答

让我们试试reindex

(a['value'].unstack(level=(2,3), fill_value=0)
     .reindex([(k,x) for k,v in meta.items() for x in v], axis=1, fill_value=0)
     .stack(level=(0,1))
     .to_frame(name='value')
)

其中adf_m.groupby(...).agg(...)。输出:

                     value
2020-08 Grp1 q1 1.0    1.0
                2.0    0.0
                3.0    0.0
                4.0    0.0
                5.0    0.0
             q2 1.0    1.0
                2.0    0.0
                3.0    0.0
                4.0    0.0
                5.0    0.0
             q3 1.0    1.0
                2.0    0.0
                3.0    0.0
2020-09 Grp1 q1 1.0   50.0
                2.0    4.0
                3.0    0.0
                4.0    3.0
                5.0    0.0
             q2 1.0   42.0
                2.0   12.0
                3.0    0.0
                4.0    0.0
                5.0    0.0
             q3 1.0   52.0
                2.0    2.0
                3.0    0.0
        Grp2 q1 1.0   98.0
                2.0    0.0
                3.0    2.0
                4.0    1.0
                5.0    0.0
             q2 1.0   89.0
                2.0    6.0
                3.0    0.0
                4.0    0.0
                5.0    0.0
             q3 1.0   86.0
                2.0    9.0
                3.0    0.0

如果您已经有了字典,您可以像搜索未遇到的键一样简单,为其指定默认值或将字典从集合库强制转换为defaultdict

例如

dict_grouped_by = df_m.groupby(['yearmonth', 'grp', 'question', 'value']).agg({'value': 'count'}).to_dict()
val_count = dict_grouped_by['value']

默认值

val_count.get(('2020-09', 'Grp2', 'q3', 3.0), 0) # returns 0

使用defaultdict

from collections import defaultdict
def_dict = defaultdict(int, val_count)
def_dict[('2020-09', 'Grp2', 'q3', 3.0)] # returns 0

相关问题 更多 >