我已经搜索了很多,但似乎没有什么可以解决这个问题。
假设什么时候df是这样的:
import pandas as pd
import numpy as np
df = pd.DataFrame([['a','b','c'], ['a',np.nan,'b'], [np.nan, 'b', 'a'], ['a', 'd', 'b']])
df
0 1 2
0 a b c
1 a NaN b
2 NaN b a
3 a d b
Run Code Online (Sandbox Code Playgroud)
期望的输出是:
0 1 2
0 a b c
3 a d b
Run Code Online (Sandbox Code Playgroud)
第 1、2 行是第 0 行的子集,因此我想删除它们。当检查一行是否是任何其他行的子集时,NaN不考虑。因此,第 1 行变为{'a','b'},从而成为一个子集。
到目前为止我尝试过的是使sets:
df.ffill(1).bfill(1).apply(set, 1)
Run Code Online (Sandbox Code Playgroud)
产生:
0 {c, a, b}
1 {a, b}
2 {a, b}
3 {d, a, b}
Run Code Online (Sandbox Code Playgroud)
但我被困在这里了。pd.DataFrame.drop_duplicates似乎对我没有帮助。
任何帮助是极大的赞赏 :)
这很难。理想情况下,您想要:
pd.Index,它的行为类似于集合,并且有一些类似集合操作的方法。)由于特定的条件,这两件事在这里做起来都很棘手,因此时间复杂度可能会变得很复杂。(我并不排除可能有比这个更巧妙的答案。)但一般来说,一旦您从精确重复测试转向子集测试,事情就会变得更加困难。
综上所述,您可以:
set.issuperset在贪婪调用中使用来any()查找重复项的索引,利用frozenset可散列的事实(感谢此处的其他答案)。复杂度仍然是 N^2 或接近它的值,但对于中等大小的数据来说这可能就足够了。
>>> df = pd.DataFrame([['a','b','c'], ['a',np.nan,'b'], [np.nan, 'b', 'a'], ['a', 'd', 'b']])
>>>
>>> seen = set()
>>> add = seen.add
>>> dupes = []
>>>
>>> for pos, row in enumerate(df.values.tolist()):
... vals = frozenset(i for i in row if isinstance(i, str))
... if any(i.issuperset(vals) for i in seen):
... dupes.append(pos)
... add(vals)
...
>>> dupes
[1, 2]
Run Code Online (Sandbox Code Playgroud)
这会让你通过 下降索引DataFrame.drop()。
| 归档时间: |
|
| 查看次数: |
574 次 |
| 最近记录: |