Pandas 如何有效地从数据帧中删除重复行

Pandas 如何有效地从数据帧中删除重复行,pandas,Pandas,我正在处理一个非常大的数据帧,我正在使用熊猫进行分析。 数据框的结构如下所示 import pandas as pd df = pd.read_csv("data.csv") df.head() Source Target Weight 0 0 25846 1 1 0 1916 1 2 25846 0 1 3 0 4748 1 4 0 16856

我正在处理一个非常大的数据帧,我正在使用熊猫进行分析。 数据框的结构如下所示

import pandas as pd

df = pd.read_csv("data.csv")
df.head()

    Source  Target  Weight
0       0   25846       1
1       0    1916       1
2   25846       0       1
3       0    4748       1
4       0   16856       1
问题是我想删除所有的重复项。在这个意义上,如果我已经有一行包含一个源和一个目标,我不希望这个信息在另一行重复。 例如,从这个意义上讲,第0行和第2行是重复的,应该只保留其中一行

消除所有重复项的简单方法是

for index, row in df.iterrows():
    df = df[~((df.Source==row.Target)&(df.Target==row.Source))]

然而,这种方法非常慢,因为我的数据帧有大约300万行。您认为有更好的方法吗?

无需像往常一样使用带有数据帧的循环。使用Series.isin方法:

因此,从这个开始:

df = pandas.DataFrame({
    'src': [0, 0, 25, 0, 0],
    'tgt': [25, 12, 0, 85, 363]
})

print(df)



src  tgt
0    0   25
1    0   12
2   25   0
3    0   85
4    0  363
然后选择src不在tgt中的所有位置:


创建两个临时列以保存minimumdf.Source、df.Target和maximumdf.Source、df.Target,然后使用duplicated方法检查重复的行:


您的源和目标似乎是相互排斥的,即您可以有一个,但不能同时有两个。为什么不将它们相加,例如25846+0,以获得唯一标识符。然后,您可以删除不需要的目标列以减少内存,然后删除重复项。如果您的权重不相同,默认情况下将采用第一个权重

df.Source += df.Target
df.drop('Target', axis=1, inplace=True)
df.drop_duplicates(inplace=True)

>>> df
   Source  Weight
0   25846       1
1    1916       1
3    4748       1
4   16856       1

这将删除实际上不重复的行。考虑DF=Pd.DATAFRAM{{SRC:[1,2,3],TGT:[2,3,1] }。@ DSM,我不认为OP意味着复制大多数熊猫电力用户的意思。鉴于提供的样本数据数量有限,这将复制OP代码的输出。是的,我想我明白了,但是IIUC OP希望删除[2,1],如果他已经看到[1,2]。我给出的示例在这种意义上没有任何重复项,但您的代码会将它们全部删除。@DSM我认为您是对的-但我将保留这一点,因为它仍然是对原始代码的无环改进。即使这是有意义的,说源和目标是位置标签,权重是一个距离:那么添加源和目标就没有意义了,如果有0,2和1,1的源/目标行呢?[哦,等等,对不起-你假设这不会发生。我仍然认为这在OP的上下文中没有意义,但你已经明确排除了这种情况。]它基于一个假设,即给定源/目标行中只有一个值,另一个值为零。在上面5行的示例中是正确的,但显然取决于对数据编码方式的了解。如果假设成立,这种方法应该是非常有效的。
import numpy as np

import pandas as pd

df = pd.DataFrame(np.random.randint(0, 5, (20, 2)), columns=["Source", "Target"])

df["T1"] = np.minimum(df.Source, df.Target)
df["T2"] = np.maximum(df.Source, df.Target)

df[~df[["T1", "T2"]].duplicated()]
df.Source += df.Target
df.drop('Target', axis=1, inplace=True)
df.drop_duplicates(inplace=True)

>>> df
   Source  Weight
0   25846       1
1    1916       1
3    4748       1
4   16856       1