如何有效地从DataFrame中删除重复的行

时间:2016-03-08 00:03:32

标签: 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       1

问题是我想要删除所有"重复"。从某种意义上说,如果我已经有一个包含SourceTarget的行,我不希望在另一行上重复此信息。 例如,行号0和2是"重复"从这个意义上讲,只保留其中一个。

摆脱所有"重复的简单方法"是

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

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

3 个答案:

答案 0 :(得分:3)

创建两个临时列以保存minimum(df.Source, df.Target)maximum(df.Source, df.Target),然后按duplicated()方法检查重复的行:

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()]

答案 1 :(得分:0)

不需要(像往常一样)使用带有数据帧的循环。使用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的所有位置:

df[~(df['src'].isin(df['tgt']) & df['tgt'].isin(df['src']))]

   src  tgt
1    0   12
3    0   85
4    0  363

答案 2 :(得分:0)

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

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