パンダのインデックスを数える


8

これは初歩的な質問のように感じますが、私はこれに非常に慣れていないので、それを解読したり、答えを見つけることができませんでした。

最終的に私がここでやろうとしているのは、特定の列の一意の値を数え、それらの一意の値のうち、一致する列に複数の一意の値があるものを特定することです。

したがって、このデータについて、私が判断しようとしているのは、すべての購入に対して「誰が」「複数のレシート」を持っているか、そして各製品カテゴリーに基づいて同じ情報を判断することです。

これまでの私のアプローチ:

次のようなデータセットがあります。

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

与えられた例は役立つと思いますが、何でも追加してください。


希望する(期待される)結果のデータセットを投稿できますか?
MaxU、2016年

回答:


5

多分あなたが探していると思います:

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などに置き換えます)


これは非常に役立ちます。私は私の質問を間違って言いました。「複数の領収書」は「複数のトランザクション、つまり複数の固有の領収書があることを意味します。」
Hasquestions氏、2016年

それを聞いてうれしい。再:あなたの質問、2つはどのように違うのですか?固有の領収書を定義するもの-「領収書」列は領収書IDですか?カテゴリは、そのレシートで購入したすべてのアイテムですか?もしそうなら、あなたreceipts_by_name = df.groupby(['name']).unique()は「領収書」の列にある答えを試してみることができると思います。別のgroupby関数を適用する必要があるだけです。
atkat12

そうですね、データセットの各行が購入のラインアイテムを表すという考え方もあるので、レシートはそのトランザクションの「レシートID」です。したがって、たとえば、ビルはトランザクション#5で2つの猫のアイテムを購入し、トランザクション#2を担当しています。したがって、彼は「リピートショッパー」ですが、2つの猫の購入が同じトランザクション中に発生したため、「リピートショッパー」ではありません。
Hasquestions氏、2016

3

正確に何を達成しようとしているのかは明確ではありません(希望する/期待されるデータセットを投稿する場合、目標を理解することは役に立ちます)...

しかし、私は推測しようとします;)

データ:

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.