pythonのDataFrameで指定した列ごとに重複行をカウントする方法

データパイプライン構築をしている際に、ある列を除いて他の列の値が重複している事象がありました。その際にDataFrameのduplicated()とsize()とreset_index()を使用しました。

サンプルコード

# 辞書型のリストでデータを作成
import pandas as pd

dict_list = [{'store_num':'00001', 'category_l':'100', 'category_m':'10', 'category_s':'1', 'item_num':'AAA', 'qty':10, 'delivery_day':'2024-05-01', 'delivery_cnt':1, 'rgdt':'2024-04-29'},
             {'store_num':'00001', 'category_l':'100', 'category_m':'10', 'category_s':'1', 'item_num':'AAA', 'qty':100, 'delivery_day':'2024-05-01', 'delivery_cnt':1, 'rgdt':'2024-04-29'},
             {'store_num':'00002', 'category_l':'200', 'category_m':'20', 'category_s':'1', 'item_num':'BBB', 'qty':20, 'delivery_day':'2024-05-01', 'delivery_cnt':1, 'rgdt':'2024-04-29'},
             {'store_num':'00002', 'category_l':'200', 'category_m':'20', 'category_s':'1', 'item_num':'BBB', 'qty':200, 'delivery_day':'2024-05-01', 'delivery_cnt':1, 'rgdt':'2024-04-29'},
             {'store_num':'00002', 'category_l':'200', 'category_m':'20', 'category_s':'1', 'item_num':'BBB', 'qty':2000, 'delivery_day':'2024-05-01', 'delivery_cnt':1, 'rgdt':'2024-04-29'},
             {'store_num':'00003', 'category_l':'100', 'category_m':'10', 'category_s':'1', 'item_num':'CCC', 'qty':30, 'delivery_day':'2024-05-01', 'delivery_cnt':1, 'rgdt':'2024-04-29'}]

df = pd.DataFrame(dict_list)

# 列のリストを作成
# column_list = df.columns.tolist()

# qty以外で重複がある行をカウントし、列名を「count」として追加
df_duplicated_sub_count = df_duplicated_sub.groupby(['store_num', 'category_l', 'category_m', 'category_s', 'item_num', 'delivery_day', 'delivery_cnt', 'rgdt']).size().reset_index(name='count')
display(df_duplicated_sub_count)
print(type(df_duplicated_sub_count))

結果

	store_num	category_l	category_m	category_s	item_num	delivery_day	delivery_cnt	rgdt	count
0 00001 100 10 1 AAA 2024-05-01 1 2024-04-29 2
1 00002 200 20 1 BBB 2024-05-01 1 2024-04-29 3

<class 'pandas.core.frame.DataFrame'>

サンプルコード解説

df_duplicated_sub.groupby()

groupbyした際のデータ型はDataFrameGroupBy型です。printしてもSQLのようにSELECTした結果が返ってきません。

print(df_duplicated_sub.groupby(['store_num', 'category_l', 'category_m', 'category_s', 'item_num', 'delivery_day', 'delivery_cnt', 'rgdt']))
print(type((df_duplicated_sub.groupby(['store_num', 'category_l', 'category_m', 'category_s', 'item_num', 'delivery_day', 'delivery_cnt', 'rgdt']))))

結果

<pandas.core.groupby.generic.DataFrameGroupBy object at 0x7bfd6d14aa40>
<class 'pandas.core.groupby.generic.DataFrameGroupBy'>

df_duplicated_sub.groupby().size()

Series型で返ってきます。グループ化で指定した列がマルチインデックスとなります。

print(type(df_duplicated_sub.groupby(['store_num', 'category_l', 'category_m', 'category_s', 'item_num', 'delivery_day', 'delivery_cnt', 'rgdt']).size()))
display(df_duplicated_sub.groupby(['store_num', 'category_l', 'category_m', 'category_s', 'item_num', 'delivery_day', 'delivery_cnt', 'rgdt']).size())

結果

<class 'pandas.core.series.Series'>
store_num  category_l  category_m  category_s  item_num  delivery_day  delivery_cnt  rgdt      
00001      100         10          1           AAA       2024-05-01    1             2024-04-29    2
00002      200         20          1           BBB       2024-05-01    1             2024-04-29    3
dtype: int64

df_duplicated_sub.groupby().size().reset_index()

マルチインデックスを列に戻します。reset_indexの引数nameを指定しないと列名が「0」となります。

df_duplicated_sub_count_no_name = df_duplicated_sub.groupby(['store_num', 'category_l', 'category_m', 'category_s', 'item_num', 'delivery_day', 'delivery_cnt', 'rgdt']).size().reset_index()
display(df_duplicated_sub_count_no_name)
print(type(df_duplicated_sub_count_no_name))

結果

	store_num	category_l	category_m	category_s	item_num	delivery_day	delivery_cnt	rgdt	0
0 00001 100 10 1 AAA 2024-05-01 1 2024-04-29 2
1 00002 200 20 1 BBB 2024-05-01 1 2024-04-29 3

<class 'pandas.core.frame.DataFrame'>

コメント

タイトルとURLをコピーしました