pandas 中的计数索引

数据挖掘 Python 熊猫 索引
2021-10-06 07:08:02

我觉得这是一个基本问题,但我对此很陌生,只是无法破解它/找到答案。

最终,我在这里要做的是计算某个列上的唯一值,然后确定这些唯一值中的哪些在匹配列中具有多个唯一值。

所以对于这个数据,我要确定的是“谁”对所有购买都有“不止一张收据”,然后根据每个产品类别确定相同的信息。

到目前为止我的方法:

我们有一个这样的数据集:

receipt,name,etc,category
1,george,xxx,fish
1,george,xxx,cat
2,george,xxx,fish
3,bill,xxx,fish
3,bill,xxx,dog
4,jill,xxx,cat
5,bill,xxx,cat
5,bill,xxx,cat
5,bill,xxx,dog
6,george,xxx,fish

那么我可以这样做:

df.set_index(['name','receipt'])

并且变得更有趣

                etc category
name   receipt
george 1        xxx     fish
       1        xxx      cat
       2        xxx     fish
bill   3        xxx     fish
       3        xxx      dog
jill   4        xxx      cat
bill   5        xxx      cat
       5        xxx      cat
       5        xxx      dog
george 6        xxx     fish

在这一点上,我觉得数据很容易处理,但我还没有弄清楚。

我感兴趣的一件事是,如果我在索引数据之前按名称对数据进行排序,则数据会按名称分组显示。在这两种情况下,索引都是相同的,所以我不知道如何在索引后使用数据的表示。

使用分类很容易找到数据

>>> orders.loc[orders['category'] == 'fish']
                etc category
name   receipt
george 1        xxx     fish
       2        xxx     fish
bill   3        xxx     fish
george 6        xxx     fish

但我想不通的是如何告诉熊猫“给我找到一张以上收据的名单”。

小问题:

  • 获取索引名称部分长度的“熊猫方式”是什么?我想我可以把name列变成一个集合并得到它的长度。但我对索引很好奇。

编辑/更新

谢谢你的回答!这是对我正在寻找的内容的说明:

我正在努力寻找“回头客”:拥有不止一张收据的人。

所以我的所有客户将是:

names: ['george','bill','jill'], ratio: 1.0

我的回头客:

names: ['george','bill'], ratio 0.66

所有“鱼”客户:

names: ['george','bill'], ratio: 0.666

我的重复“鱼”客户:

names: ['george'], ratio: 0.333

我认为给出的示例看起来很有帮助,但可以随意添加任何内容。

2个回答

我想也许你正在寻找:

receipts_by_name_x_cat = df.groupby(['name','category']).count()

或者,如果您只想要所有类别的总数:

receipts_by_name = df.groupby(['name']).count()

然后,您可以搜索拥有多个的人:

receipts_by_name[receipts_by_name['receipt']>1]

而且,您可以通过键入以下内容找到索引的长度:

len(df.index.get_level_values(0))

假设名称是第一个索引列(否则替换为 1、2 等)

目前还不太清楚您到底想实现什么(如果您发布所需/预期的数据集,这将有助于了解您的目标)......

但我会尝试猜测;)

数据:

In [100]: df
Out[100]:
   receipt    name  etc category
0        1  george  xxx     fish
1        1  george  xxx      cat
2        2  george  xxx     fish
3        3    bill  xxx     fish
4        3    bill  xxx      dog
5        4    jill  xxx      cat
6        5    bill  xxx      cat
7        5    bill  xxx      cat
8        5    bill  xxx      dog
9        6  george  xxx     fish

设置虚拟列count,显示分组的行数name并使用方法过滤(查询)它.query()

In [101]: (df.assign(count=df.groupby('name').receipt.transform('size'))
     ...:    .query("category in ['dog','cat'] and count > 1"))
     ...:
Out[101]:
   receipt    name  etc category  count
1        1  george  xxx      cat      4
4        3    bill  xxx      dog      5
6        5    bill  xxx      cat      5
7        5    bill  xxx      cat      5
8        5    bill  xxx      dog      5

或者您可以按几列分组并过滤结果组:

In [102]: df.groupby(['name','category']).filter(lambda x: len(x) > 2)
Out[102]:
   receipt    name  etc category
0        1  george  xxx     fish
2        2  george  xxx     fish
9        6  george  xxx     fish