我正在尝试根据数据框中的两列删除重复的“Box”行:
import pandas as pd
d = {'Box': ['A1', 'A1', 'A2', 'A3', 'A4', 'A5', 'A5'], 'Status': ['Prep', 'Ready', 'Prep', 'Prep', 'Ready', 'Prep', 'Ready'], 'Week':[11, 12, 12, 13, 11, 10, 11], 'QTY': [6, 7, 6, 8, 5, 8, 7]}
df = pd.DataFrame(data=d)
- 如果有重复的 Box 编号,则取带 min(Week) 的编号
- 如果有重复的 Box 号码,则取 Status !=Ready(不等于就绪)
到目前为止我已经尝试过:
df1= df.drop_duplicates(subset=["Week", "Box"], keep=False)
如果两个条件都满足,我想优先考虑 Status!= Ready 条件。
预期结果是:
最佳答案
DataFrame.drop_duplicates(...)
默认保留根据您指定的列子集找到的第一个项目。
换句话说,df.drop_duplicates('Box')
将保留 Box
每个唯一值的第一个值,并删除其余值。
所以我们只需要对数据框进行排序,以便我们想要保留的项目是我们遇到的第一个项目。
uniques = df.sort_values('Week').sort_values('Status').drop_duplicates('Box')
这做出了很多假设:
- 您的数据很小,因此像这样排序两次并不会太昂贵。
- 您没有其他可能会干扰此操作的
Status
值。Prep
按字典顺序恰好位于Ready
之前。 - 您没有找到
Week
值在Status
中具有Ready
的示例 - 因为我们按Status
排序最后,我们更加重视这个条件。如果您想首先按周
进行过滤,则可以反转它们。
编辑:
您发布的数据:
>>> import pandas as pd
>>> d = {'Box': ['A1', 'A1', 'A2', 'A3', 'A4', 'A5', 'A5'], 'Status': ['Prep', 'Ready', 'Prep', 'Prep', 'Ready', 'Prep', 'Ready'], 'Week':[11, 12, 12, 13, 11, 10, 11], 'QTY': [6, 7, 6, 8, 5, 8, 7]}
>>> df = pd.DataFrame(data=d)
>>> df.sort_values('Status').sort_values('Week').drop_duplicates('Box').sort_index()
Box QTY Status Week
0 A1 6 Prep 11
2 A2 6 Prep 12
3 A3 8 Prep 13
4 A4 5 Ready 11
5 A5 8 Prep 10
对于上面的假设 2,我建议对您的状态进行排序,然后基于此添加一列。
order = { 'Prep' : 1, 'Ready' : 2 }
df['status_order'] = df['Status'].apply(lambda x: order[x])
然后您可以按此列而不是状态
排序。这概括为处理非Ready
状态的重复项。
关于python - 如何根据其他列中的一个而不是两个条件删除重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56434677/