当前位置: 首页 > 知识库问答 >
问题:

计数多个列中的所有值组合

袁阿苏
2023-03-14

以下是一个以1、2或3颗星评级的项目示例。我试图每月统计所有项目评分组合(星级)。

在下面的例子中,第10项在第1个月被评定,两个等级等于1,一个等级等于2,一个等级等于3。

inp = pd.DataFrame({'month':[1,1,1,1,1,2,2,2], 
                    'item':[10,10,10,10,20,20,20,20], 
                    'star':[1,2,1,3,3,2,2,3]}
                  )

 month item star
0   1   10  1
1   1   10  2
2   1   10  1
3   1   10  3
4   1   20  3
5   2   20  2
6   2   20  2
7   2   20  3

对于给定的上述输入帧输出应该是:

   month    item    star_1_cnt  star_2_cnt  star_3_cnt
0   1       10      2           1           1
1   1       20      0           0           1
2   2       20      0           2           1

我试图从以下代码开始解决这个问题,该代码的结果仍然需要转换为所需的输出帧格式,并且给出了错误的答案:

1   20  3   (1, 1)
2   20  3   (1, 1)

无论如何,应该有一个更好的方法来创建输出表,然后完成这个:

months = [1,2]
items = [10,20]
stars = [1,2,3]

d = {'month': [], 'item': [], 'star': [], 'star_cnts': [] }

for month in months:
    for star in stars:
        for item in items:
            star_cnts=dict(inp[(inp['item']==item) & (inp['star']==star)].value_counts()).values()
            d['month'].append(month)
            d['item'].append(item)
            d['star'].append(star)
            d['star_cnts'].append(star_cnts)
            
pd.DataFrame(d)

    month   item    star    star_cnts
0   1       10      1       (2)
1   1       20      1       ()
2   1       10      2       (1)
3   1       20      2       (2)
4   1       10      3       (1)
5   1       20      3       (1, 1)
6   2       10      1       (2)
7   2       20      1       ()
8   2       10      2       (1)
9   2       20      2       (2)
10  2       10      3       (1)
11  2       20      3       (1, 1)

共有3个答案

颛孙钱青
2023-03-14

系列。数值计数系列。取消堆栈以转换为数据帧

out = inp.value_counts()\
         .unstack('star', fill_value=0)\
         .rename(lambda x: f'star_{x}_cnt', axis=1)\
         .reset_index().rename_axis(columns=None)

print(out)

   month  item  star_1_cnt  star_2_cnt  star_3_cnt
0      1    10           2           1           1
1      1    20           0           0           1
2      2    20           0           2           1
李谦
2023-03-14

一个选项,带有pivot_表:

(inp
.pivot_table(index=['month', 'item'], 
             values = 'star', 
             columns='star', 
             aggfunc='size', 
             fill_value = 0)
.rename(columns = lambda col: f"star_{col}_cnt")
.rename_axis(columns = None)
.reset_index()
)
   month  item  star_1_cnt  star_2_cnt  star_3_cnt
0      1    10           2           1           1
1      1    20           0           0           1
2      2    20           0           2           1

另一个选项,使用Groupby(pivot_table是Groupby展开堆栈的包装器):

(inp
.groupby(['month', 'item', 'star'])
.size()
.unstack(fill_value = 0)
.rename(columns = lambda col: f"star_{col}_cnt")
.rename_axis(columns = None)
.reset_index()
)

   month  item  star_1_cnt  star_2_cnt  star_3_cnt
0      1    10           2           1           1
1      1    20           0           0           1
2      2    20           0           2           1

另一个选项,pd.get_dummiesGroupby

(pd.get_dummies(inp, columns=['star'])
.groupby(['month', 'item'])
.sum()
.add_suffix('_cnt')
.reset_index()
)
   month  item  star_1_cnt  star_2_cnt  star_3_cnt
0      1    10           2           1           1
1      1    20           0           0           1
2      2    20           0           2           1

就性能而言,只有测试才能知道——我希望pivot_table比团购慢

沃博裕
2023-03-14

您可以对整个数据帧使用value_counts,并取消堆栈:

out = (
 inp.value_counts()
    .unstack('star', fill_value=0)
 )

或者,您可以使用交叉表

因为它需要1D数据作为输入,所以可以使用元组:

cols = ['month','item']
out = pd.crosstab(inp[cols].apply(tuple, axis=1), inp['star'])

out.index = pd.MultiIndex.from_tuples(out.index, names=cols)

输出:

star        1  2  3
month item         
1     10    2  1  1
      20    0  0  1
2     20    0  2  1

@ansev已经很好地证明了这一点

(inp.value_counts()
    .unstack('star', fill_value=0)
    .rename(lambda c: f'star_{c}_cnt', axis=1)
    .reset_index()
    .rename_axis(columns=None)
 )

输出:

   month  item  star_1_cnt  star_2_cnt  star_3_cnt
0      1    10           2           1           1
1      1    20           0           0           1
2      2    20           0           2           1
 类似资料:
  • 问题内容: 给定多个长度可能不同的列表,我想遍历值的所有组合,每个列表中的一项。例如: 然后我想要的输出是: 我想遍历 合并 列表。我该如何完成? 问题答案: 应该可以。 请注意,它返回一个迭代器,因此,如果仅要迭代一次,则无需将其转换为列表。 例如。

  • 我正在尝试编写一种方法来将数组置换为所有可能的排列。我将每个数组以ArrayList的形式,翻转两个元素,然后将ArrayList返回到ArrayList of ArrayList。如果我在翻转两个元素后将每个数组打印到屏幕上,则按预期进行打印。[1,2,3]前两个元素翻转打印为[2,1,3],但当我将置换的ArrayList添加到另一个ArrayList时,它们都打印为[1,2,3] 代码: 输

  • 问题内容: 如何通过关联键添加所有列值?请注意,键集是动态的。 输入数组: 所需结果: 问题答案:

  • 问题内容: 我有以下SQL: 这将按照我期望的方式对所有null进行计数。但是,我想使用此sql遍历目录中的每个表,例如在 有人可以提供执行此操作所需的sql吗,我对使用游标一无所知。 谢谢 问题答案: 无需游标。只需将您设置为 然后从此更改您的条款 到 所以整个代码…

  • 问题内容: 我试图弄清楚如何编写一个查询多个列中的值的查询,结果表在每个列中对 任何 列的每个可能值都有一个计数。 示例:说我有 mytable 我想要一个查询,在每列中计算a和b,产生类似以下内容的结果: 我知道我可以通过 group by 轻松地对单个列执行此操作: 但是是否可以对 每一 列都执行此操作? 我正在使用SQL Server 2008(T-SQL)。在此先感谢您的帮助! 问题答案:

  • 我试图创建一个数组或ArrayList,它包含三个独立的链表。 假设我有一个部门数组(销售、媒体、船员),每个元素都是一个循环链接的名称、标题、id和支付率。 示例: 我希望能够检索到特定链表中的节点,如部门(销售)。下一步,等等。这是我当前的代码: 另外还有两个旁注,我目前可以从最右边插入,但如何才能从最左边插入。另外,如何删除节点?我在网上看到的一切都显示删除一个只有一个值的节点,但我有多个值