Pandas df.drop_duplicates() 関数
df.drop_duplicates()Pandasで重複行を削除するための関数です。
データ収集と統合のプロセスでは、重複データはよくある問題です。drop_duplicates()指定した列またはすべての列に基づいて重複する行を識別して削除し、最初または最後に出現したレコードを保持することができます。これはデータの重複排除、データの一意性の確保に非常に役立ちます。
基本構文とパラメータ
drop_duplicates()DataFrameのメンバー関数であり、ドット演算子で.呼び出します。
構文形式
DataFrame.drop_duplicates(subset=None, keep='first', inplace=False, ignore_index=False)
パラメータの説明
| パラメータ | 型 | 必須かどうか | 説明 | デフォルト値 |
|---|---|---|---|---|
| subset | column label または list | 任意 | 重複を判断するために使用する列を指定します。もしNoneの場合は、すべての列を使用します。単一の列名または列名のリストを指定できます。 |
None |
| keep | str または False | 任意 | どの重複レコードを保持するかを指定します。'first'最初のレコードを保持;'last'最後のレコードを保持;Falseすべての重複レコードを削除します。 |
'first' |
| inplace | bool | 任意 | もしTrueの場合は、元のDataFrameを直接変更し、新しいオブジェクトを返しません;もしFalseの場合は、新しいDataFrameを返し、元のデータは変更されません。 |
False |
| ignore_index | bool | 任意 | もしTrueの場合は、結果のインデックスをリセットし、0から番号を付け直します;もしFalseの場合は、元のインデックスを保持します。 |
False |
戻り値の説明
- 新しいDataFrameを返します(もし
inplace=False)、またはNone(もしinplace=True)。 - 返されるDataFrameには重複する行は含まれません。
例
一連の例を通じて、完全に習得しましょうdrop_duplicates()の使い方。
例1:完全に重複する行を削除
デフォルトでは、すべての列に基づいて重複行かどうかを判断します。
例
import pandas as pd
import numpy as np
# 重複行を含むDataFrameを作成
data = {
'姓名': ['张三', '李四', '张三', '王五', '李四'],
'年龄': [25, 30, 25, 35, 30],
'部门': ['技术', '市场', '技术', '技术', '市场']
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("=" * 50)
# 重複行を削除し、最初に出現したレコードを保持
df_cleaned = df.drop_duplicates()
print(重複行を削除した後のデータ:)
print(df_cleaned)
import numpy as np
# 重複行を含むDataFrameを作成
data = {
'姓名': ['张三', '李四', '张三', '王五', '李四'],
'年龄': [25, 30, 25, 35, 30],
'部门': ['技术', '市场', '技术', '技术', '市场']
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("=" * 50)
# 重複行を削除し、最初に出現したレコードを保持
df_cleaned = df.drop_duplicates()
print(重複行を削除した後のデータ:)
print(df_cleaned)
実行結果の期待値:
原始数据:
姓名 年龄 部门
0 张三 25 技术
1 李四 30 市场
2 张三 25 技术
3 王五 35 技术
4 李四 30 市场
==================================================
删除重复行后的数据:
0 姓名 年龄 部门
0 张三 25 技术
1 李四 30 市场
3 王五 35 技术
コードの解説:
- 元のデータでは、0行目と2行目が完全に同じです(张三、25歳、技術部門)。
- 1行目と4行目も完全に同じです(李四、30歳、市場部門)。
- 使用
drop_duplicates()デフォルトパラメータで、重複する行を削除し、最初に出現した位置を保持しました。
例2:指定した列に基づいて重複行を削除
使用できますsubsetパラメータは特定の列だけに基づいて重複を判断します。
例
import pandas as pd
import numpy as np
# DataFrameを作成
data = {
'姓名': ['张三', '李四', '张三', '王五'],
'年龄': [25, 30, 28, 35], # 张三は2回出現しますが、年齢が異なります
'部门': ['技术', '市场', '技术', '市场']
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("=" * 50)
# 「姓名」列のみに基づいて重複を判断
df_cleaned = df.drop_duplicates(subset=['姓名'])
print("氏名列に基づいて重複を削除した後のデータ:")
print(df_cleaned)
print("=" * 50)
# 「姓名」と「部门」の2列に基づいて重複を判断
df_cleaned2 = df.drop_duplicates(subset=['姓名', '部门'])
print("氏名と部門列に基づいて重複を削除した後のデータ:")
print(df_cleaned2)
import numpy as np
# DataFrameを作成
data = {
'姓名': ['张三', '李四', '张三', '王五'],
'年龄': [25, 30, 28, 35], # 张三は2回出現しますが、年齢が異なります
'部门': ['技术', '市场', '技术', '市场']
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("=" * 50)
# 「姓名」列のみに基づいて重複を判断
df_cleaned = df.drop_duplicates(subset=['姓名'])
print("氏名列に基づいて重複を削除した後のデータ:")
print(df_cleaned)
print("=" * 50)
# 「姓名」と「部门」の2列に基づいて重複を判断
df_cleaned2 = df.drop_duplicates(subset=['姓名', '部门'])
print("氏名と部門列に基づいて重複を削除した後のデータ:")
print(df_cleaned2)
実行結果の期待値:
原始数据:
姓名 年龄 部门
0 张三 25 技术
1 李四 30 市场
2 张三 28 技术 # 虽然姓名重复,但年龄不同
3 王五 35 市场
==================================================
根据姓名列删除重复后的数据:
姓名 年龄 部门
0 张三 25 技术 # 保留第一条张三的记录
2 张三 28 技术
3 王五 35 市场
==================================================
根据姓名和部门列删除重复后的数据:
参数
姓名 年龄 部门
0 张三 25 技术
1 李四 30 市场
3 王五 35 市场
コードの解説:
- 姓名列で判断すると、0行目と2行目の姓名がどちらも「张三」であるため、重複行と見なされ、0行目のみが保持されます。
- 姓名と部门の2列で判断すると、0行目と2行目の姓名と部门が両方とも同じであるため、0行目が保持されます。
例3:最後の重複レコードを保持
使用keep='last'パラメータで最後に出現した重複レコードを保持できます。
例
import pandas as pd
import numpy as np
# 重複行を含むDataFrameを作成
data = {
'学号': ['S001', 'S002', 'S001', 'S003', 'S002'],
'姓名': ['张三', '李四', '张三', '王五', '李四'],
'成绩': [85, 90, 88, 92, 85] # 同じ学号でも、成績が異なる場合があります
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("=" * 50)
# 最初のレコードを保持(デフォルト)
df_first = df.drop_duplicates(subset=['学号'], keep='first')
print("保留第一条重复记录:")
print(df_first)
print("=" * 50)
# 最後のレコードを保持
df_last = df.drop_duplicates(subset=['学号'], keep='last')
print("保留最后一条重复记录:")
print(df_last)
import numpy as np
# 重複行を含むDataFrameを作成
data = {
'学号': ['S001', 'S002', 'S001', 'S003', 'S002'],
'姓名': ['张三', '李四', '张三', '王五', '李四'],
'成绩': [85, 90, 88, 92, 85] # 同じ学号でも、成績が異なる場合があります
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("=" * 50)
# 最初のレコードを保持(デフォルト)
df_first = df.drop_duplicates(subset=['学号'], keep='first')
print("保留第一条重复记录:")
print(df_first)
print("=" * 50)
# 最後のレコードを保持
df_last = df.drop_duplicates(subset=['学号'], keep='last')
print("保留最后一条重复记录:")
print(df_last)
実行結果の期待値:
原始数据:
学号 姓名 成绩
0 S001 张三 85
1 S002 李四 90
2 S001 张三 88 # 同一个人,成绩不同
3 S王五 92
4 S002 李四 85 # 同一个人,成绩不同
==================================================
保留第一条重复记录:
学号 姓名 成绩
0 S001 张三 85 # 保留第一个85分
1 S002 李四 90 # 保留第一个90分
3 王五 92
==================================================
保留最后一条重复记录:
学号 姓名 成绩
2 S001 张三 88 # 保留最后一个88分
3 王五 92
4 S002 李四 85 # 保留最后一个85分
コードの解説:
- 学号 S001 には2つのレコードがあり、成績はそれぞれ85と88です。使用して
keep='first'85点のレコードを保持し、keep='last'88点のレコードを保持します。 - 学号 S002 にも同様に2つのレコードがあり、成績はそれぞれ90と85です。
- 業務要件に応じて、最初のレコードを保持するか最後のレコードを保持するかを選択します。
例4:すべての重複レコードを削除
使用keep=Falseすべての重複レコードを削除し、完全に重複しない行だけを保持できます。
例
import pandas as pd
import numpy as np
# DataFrameを作成
data = {
'A': [1, 1, 2, 2, 3],
'B': [1, 1, 2, 2, 3],
'C': [1, 2, 3, 3, 5]
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("=" * 50)
# すべての重複行を削除(重複を一切保持しない)
df_cleaned = df.drop_duplicates(keep=False)
print(重複する行をすべて削除した後のデータ:)
print(df_cleaned)
import numpy as np
# DataFrameを作成
data = {
'A': [1, 1, 2, 2, 3],
'B': [1, 1, 2, 2, 3],
'C': [1, 2, 3, 3, 5]
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("=" * 50)
# すべての重複行を削除(重複を一切保持しない)
df_cleaned = df.drop_duplicates(keep=False)
print(重複する行をすべて削除した後のデータ:)
print(df_cleaned)
実行結果の期待値:
原始数据: A B C 0 1 1 1 1 1 1 2 # 与第0行A和B相同,是重复行 2 2 2 3 3 2 2 3 # 与第2行完全相同,是重复行 4 3 3 5 ================================================== 删除所有重复行后的数据: A B C 4 3 3 5
コードの解説:
- 0行目と1行目のA列とB列の値が同じで、重複行です。そのため、
keep=False2つの行は両方とも削除されます。 - 2行目と3行目も同様に完全に重複しているため、両方とも削除されます。
- 4行目だけが完全に一意であるため、保持されます。
例5:インデックスをリセット
重複行を削除した後、元のインデックスが連続しなくなる場合があります。使用してignore_index=Trueインデックスをリセットします。
例
import pandas as pd
import numpy as np
# 重複行を含むDataFrameを作成
data = {
'姓名': ['张三', '李四', '张三', '王五'],
'城市': ['北京', '上海', '北京', '广州']
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("=" * 50)
# 重複行を削除し、インデックスをリセットしない
df_cleaned1 = df.drop_duplicates()
print("删除重复行(保留原始索引):")
print(df_cleaned1)
print("=" * 50)
# 重複行を削除し、インデックスをリセット
df_cleaned2 = df.drop_duplicates(ignore_index=True)
print("删除重复行(重置索引):")
print(df_cleaned2)
import numpy as np
# 重複行を含むDataFrameを作成
data = {
'姓名': ['张三', '李四', '张三', '王五'],
'城市': ['北京', '上海', '北京', '广州']
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("=" * 50)
# 重複行を削除し、インデックスをリセットしない
df_cleaned1 = df.drop_duplicates()
print("删除重复行(保留原始索引):")
print(df_cleaned1)
print("=" * 50)
# 重複行を削除し、インデックスをリセット
df_cleaned2 = df.drop_duplicates(ignore_index=True)
print("删除重复行(重置索引):")
print(df_cleaned2)
実行結果の期待値:
原始数据:
姓名 城市
0 张三 北京
1 李四 上海
2 张三 北京
3 王五 广州
==================================================
删除重复行(保留原始索引):
姓名 城市
0 张三 北京
1 李四 上海
3 王五 广州
==================================================
删除重复行(重置索引):
姓名 城市
0 张三 北京
1 李四 上海
2 王五 广州
コードの解説:
- 使用しない
ignore_index場合、2行目を削除すると、インデックスは0、1、3となり、連続しません。 - 使用
ignore_index=True後、インデックスは0から再度番号が付けられ、0、1、2となります。
例6:他の操作と組み合わせる
drop_duplicates()他のDataFrame操作と組み合わせて使用できます。
例
import pandas as pd
import numpy as np
# データベースから取得したデータをシミュレートする
data = {
'注文番号': ['O001', 'O002', 'O001', 'O003', 'O002', 'O004'],
'顧客名': ['张三', '李四', '张三', '王五', '李四', '赵六'],
'金額': [100, 200, 100, 300, 200, 400],
'日付': ['2024-01-01', '2024-01-02', '2024-01-01', '2024-01-03', '2024-01-02', '2024-01-04']
}
df = pd.DataFrame(data)
print("元の注文データ:")
print(df)
print("=" * 50)
# 重複注文がいくつあるか確認する
print(f"総行数: {len(df)}")
print(f"重複除去後の行数: {len(df.drop_duplicates())}")
print(f"重複行数: {len(df) - len(df.drop_duplicates())}")
print("=" * 50)
# 実際に重複を除去し、最初のレコードを保持し、必要な列のみを残す
df_unique = df.drop_duplicates(subset=['注文番号'])[['注文番号', '顧客名', '金額']]
print("重複除去後の注文データ:")
print(df_unique)
import numpy as np
# データベースから取得したデータをシミュレートする
data = {
'注文番号': ['O001', 'O002', 'O001', 'O003', 'O002', 'O004'],
'顧客名': ['张三', '李四', '张三', '王五', '李四', '赵六'],
'金額': [100, 200, 100, 300, 200, 400],
'日付': ['2024-01-01', '2024-01-02', '2024-01-01', '2024-01-03', '2024-01-02', '2024-01-04']
}
df = pd.DataFrame(data)
print("元の注文データ:")
print(df)
print("=" * 50)
# 重複注文がいくつあるか確認する
print(f"総行数: {len(df)}")
print(f"重複除去後の行数: {len(df.drop_duplicates())}")
print(f"重複行数: {len(df) - len(df.drop_duplicates())}")
print("=" * 50)
# 実際に重複を除去し、最初のレコードを保持し、必要な列のみを残す
df_unique = df.drop_duplicates(subset=['注文番号'])[['注文番号', '顧客名', '金額']]
print("重複除去後の注文データ:")
print(df_unique)
実行結果の想定:
原始订单数据:
订单号 客户名 金额 日期
0 O001 张三 100 2024-01-01
1 O002 李四 200 2024-01-02
2 O001 张三 100 2024-01-01 # 重复订单
3 O003 王五 300 2024-01-03
4 O002 李四 200 2024-01-02 # 重复订单
5 O004 赵六 400 2024-01-04
================================================++
总行数: 6
去重后行数: 4
重复行数: 2
コードの解説:
- 元のデータは6行あり、2つの重複注文(O001とO002がそれぞれ2回出現)が存在する。
- 使用する
drop_duplicates(subset=['订单号'])注文番号に基づいて重複を除去する。 - 列選択と組み合わせて
[['注文番号', '顧客名', '金額']]、必要な列のみを保持する。
注意事項
drop_duplicates()デフォルトでは元のDataFrameは変更されない。元のDataFrameを変更したい場合は、使用するinplace=Trueパラメータ。- 使用する
subsetパラメータを使用する場合、指定した列のみで重複を判断し、他の列の値は判断に影響しない。 - 使用する
keep=Falseすべての重複行を削除するため、データが大量に失われる可能性がある。慎重に使用すること。 - 重複データを削除する前に、重複の原因を分析し、削除操作がビジネスロジックに適合していることを確認することをお勧めする。
- データに欠損値(NaN)がある場合、デフォルトではそれらを同じ値として扱って比較する。
その他の拡張